Given a sorted array of ints for example
a = [0,1,2,5,6,9];
I would like to identify the ranges like
[
[0,1,2],
[5,6],
[9]
]
So far I have tried a double/triple loop but it nests to really nasty code. Maybe this problem can be solved using recursion or other smart tricks?
Additional example:
input
b = [0,1,5,6,7,9];
output
[
[0,1],
[5,6,7],
[9]
]
Given a sorted array of ints for example
a = [0,1,2,5,6,9];
I would like to identify the ranges like
[
[0,1,2],
[5,6],
[9]
]
So far I have tried a double/triple loop but it nests to really nasty code. Maybe this problem can be solved using recursion or other smart tricks?
Additional example:
input
b = [0,1,5,6,7,9];
output
[
[0,1],
[5,6,7],
[9]
]
Share
Improve this question
edited Dec 20, 2017 at 13:25
Nitin Dhomse
2,6021 gold badge14 silver badges26 bronze badges
asked Dec 20, 2017 at 13:10
ajthinkingajthinking
4,53811 gold badges49 silver badges91 bronze badges
9
|
Show 4 more comments
4 Answers
Reset to default 15Iterate with Array#reduce
, and whenever the last number is not equal to the new number - 1, add another sub array. Add the current number to the last sub array:
const a = [0,1,2,5,6,9];
const result = a.reduce((r, n) => {
const lastSubArray = r[r.length - 1];
if(!lastSubArray || lastSubArray[lastSubArray.length - 1] !== n - 1) {
r.push([]);
}
r[r.length - 1].push(n);
return r;
}, []);
console.log(result);
Array.reduce like @OriDrori has done works well.
Another idea is just using a simple for loop, and slice.
function groupArray(a) {
const ret = [];
if (!a.length) return ret;
let ixf = 0;
for (let ixc = 1; ixc < a.length; ixc += 1) {
if (a[ixc] !== a[ixc-1] + 1) {
ret.push(a.slice(ixf, ixc));
ixf = ixc;
}
}
ret.push(a.slice(ixf, a.length));
return ret;
}
console.log(JSON.stringify(groupArray([0,1,2,5,6,9])));
This is what I came up with:
const a = [0,1,2,5,6,9];
const solution = (arr, expected = 0, group = []) =>
arr.reduce((acc, c, i) =>
((c === expected
? (group.push(c), expected++)
: (acc.push(group), group = [c], expected=++c)),
(i === arr.length-1 && acc.push(group)),
acc), []);
console.log(solution(a));
You can use a normal for loop and check the difference between current and previous number
var a = [0, 1, 2, 5, 6, 7, 9];
// this variable will contain arrays
let finalArray = [];
// Create a recursive function
function checkPrevNextNumRec(array) {
let tempArr = [];
// if the array contaon only 1 element then push it in finalArray and
// return it
if (array.length === 1) {
finalArray.push(array);
return
}
// otherside check the difference between current & previous number
for (let i = 1; i < array.length; i++) {
if (array[i] - array[i - 1] === 1) {
// if current & previous number is 1,0 respectively
// then 0 will be pushed
tempArr.push(array[i - 1]);
} else {
// if current & previous number is 5,2 respectively
// then 2 will be pushed
tempArr.push(array[i - 1])
// create a an array and recall the same function
// example from [0, 1, 2, 5, 6, 9] after removing 0,1,2 it
// will create a new array [5,6,9]
let newArr = array.splice(i);
finalArray.push(tempArr);
checkPrevNextNumRec(newArr)
}
// for last element if it is not consecutive of
// previous number
if (i === array.length - 1) {
tempArr.push(array[i]);
finalArray.push(tempArr)
}
}
}
checkPrevNextNumRec(a)
console.log(finalArray)
a = [0,1,2,5,6,9, 12];
, what will be the output? – Durga Commented Dec 20, 2017 at 13:13