Convert array of numbers into range groups.
by mberkom
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.8.0/lodash.min.js"></script>
<p>Converts an array of integers into an array of groups of integers based on sequential distances between numbers.</p>
<br />
<p>Dependent on <a href="http://lodash.com/">Lo-Dash</a></p>
<br />
<p>[1,2,3,4,6,8,10] becomes: </p>
<br />
<pre>
[<span id="content"></span>]
</pre>
JavaScript
var rangeGroups = function(unsortedArray) {
var array = _.sortBy(unsortedArray, function (item) {
return parseInt(item, 10);
}),
groups = [],
distancesBack = [],
distancesForward = [];
_(array).forEach(function (currentItem, index) {
var lastGroup = _.last(groups);
var previousItem = array[index - 1],
distanceBack = currentItem - previousItem,
nextItem = array[index + 1],
distanceForward = (nextItem) ? nextItem - currentItem : null,
// Applies the the third-last items
// if (distanceBack === distancesBack[0])
// - The current item's distance back is equal to the previous item's
// if (distanceBack !== distancesBack[0] && distanceForward === distancesForward[0] && (distancesBack[1] && distancesBack[0] != distancesBack[1]))
// - The current item's distance back is not equal to the previous item's
// - The current item's distance forward is equal to the previous item's
// - There is a second distance back and the first distance back is not equal to the second distance back.
ifDistancesBack = distancesBack[0] && (distanceBack === distancesBack[0] || (distanceBack !== distancesBack[0] && distanceForward === distancesForward[0] && (distancesBack[1] !== undefined && distancesBack[0] != distancesBack[1]))),
// Applies only to the second item in the list
// If its distance forward is the same as the first item's
// distance forward, add it to the existing group
ifNotDistancesBack = !distancesBack[0] && distanceForward === distancesForward[0];
if (index > 0 && (ifDistancesBack || ifNotDistancesBack)) {
// Add to last group if...
// "previousDistanceBack === null" - we haven't yet recorded a previousDistanceBack
// "distanceBack === previousDistanceBack" - the...