4

I have an array like

var arr = [12, 13, 14, 17, 18, 19, 20]

I was wondering how I could iterate through the array so that I can split this array into 2 arrays based on the sequences ? i.e. basically if i+1 != true make it a new array

var arr = [12, 13, 14]
var arr2 = [17,18,19,20]

I am using lodash and have tried a number of for statements using splice but Im getting a bit confused ? Appreciate any help

3
  • 1
    little more information please how you want to split - the split after 3 elements is pretty easy, is that all you need? Commented Jun 2, 2013 at 18:57
  • 2 arrays with equals half? Commented Jun 2, 2013 at 18:57
  • I need the split to recognize when the sequence has stopped ? i.e. 12, 13, 14 - then there is a break and the sequence doesnt start again until 17, 18, 19. i.e. i+1 != true split to new array ? Commented Jun 2, 2013 at 18:58

4 Answers 4

3

Example on jsFiddle

var a = [1, 2, 3, 5, 6, 7];

var r = [];
var t = [];

for (var i = 0; i < a.length; ++i)
{
    if (i == 0)
    {
        t.push(a[i]); // add the first element and continue
        continue;
    }
    if (a[i - 1] != (a[i] - 1))
    {
        // if the current is not sequential
        // add the current temporary array to arrays result
        r.push(t);

        // clear the temporary array and start over
        t = [];
    }

    t.push(a[i]);
}
r.push(t);

r will contain all your arrays

Minified version

function seq(e,t,n,r){t=[];n=[];for(r=0;r<e.length;++r){if(!r){n.push(e[r]);continue}if(e[r-1]!=e[r]-1){t.push(n);n=[]}n.push(e[r])}t.push(n);return t}

var result = seq([1, 2, 3, 5, 6, 7]);
Sign up to request clarification or add additional context in comments.

Comments

2

Here's a another, more dense approach, which uses underscore's quite convenient groupBy and values methods:

var origin = [12,13,14,15,17,18,19,21,22,23];
var c = 0, result = _.values( _.groupBy(origin, function(el, i, arr) { 
  return i ? c+= (1 !== el - arr[i-1]) : 0; }) );

As a result, result archive will contain all the sequences as elements. Here's the JSFiddle to play with.

Explanation: groupBy groups the source array with help of the callback (which returns a new sequence number each time the difference between the currently processed element (el) and the previous one (arr[i-1]) is bigger than 1. It returns an object, though, so I have to put it through _.values; you may or may not this step.

I wonder is that possible to request something like groupByInArray function? Should be trivial to implement, but might be very useful in situations like this.

5 Comments

great! thanks heaps. yeah i think something like groupBy would be great. I even have a scenario like [[12, 0], [13, 0], [14, 0], [18,0], [19,1], [20,0]] where I need to split this too ? So its like [[12, 0], [13, 0], [14, 0]] and [[18,0], [19,1], [20,0]]
If I understand you correctly, you can reuse this function with a minor change: replace checking el - arr[i-1] with el[0] - arr[i-1][0]. Demo
yeah awesome! thanks heaps. I was just wondering I mean if you had a groupByInArray that it would also support these scenarios too! Would be an unreal add to underscore lib
I meant pull request to Underscore library itself.
ahh, i didn´t even know something like this existed, sounds and looks just like haskell (at least a little), loving it :)
0

Do you mean like this?

function split(arr) {
    var res = [];
    var subres = [];
    for (var i = 0; i < arr.length; i++) {
        var length = subres.length;
        if (length === 0 || subres[length - 1] === arr[i] - 1) {
            subres.push(arr[i]);
        } else {
            res.push(subres);
            subres = [arr[i]];
        }
    }
    res.push(subres);
    return res;
}

2 Comments

yes! thanks a lot. im not sure if this can be made faster using lodash or underscore if you are familiar with those ?
@Andy using either library would not make anything faster.
0

try this :)

var array = [12,13,14,4567,789,0]; //e.g.
var index;
var previous = array[0];
for (var index = 1; index++; index < array.length) {
  if (previous + 1 == array[index]) {
    previous = array[index]; //++
  } else {
    break;
  }
}
var firstPart = array.slice(0, index + 1);
var secondPart = array.slice(index + 1);

http://jsfiddle.net/zajnH/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.