Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subset of array by evaluating element

I am trying to obtain a series of subsets from an array in javascript using underscore. This is what I would like to achieve:

Original array: [1,1,1,2,2,2,0,0,0,1,1,1]
Expected result: [1,1,1] [2,2,2] [0,0,0] [1,1,1]

When I use the filter method from underscore, I get three arrays: [1,1,1,1,1,1] [2,2,2] [0,0,0]; I would like that the last array of 1's would not mix.

What I've tried:

_.filter(array, function(e){
     return e === 1;
})

The criteria to split the original array is that the consecutive equal numbers must form a new array, but if the number appears later in the original array, that consecutive equal number must form a new array.

Is there a way to do this using underscore or should it be done with loops?

Thanks

like image 442
rpabon Avatar asked Nov 18 '25 17:11

rpabon


2 Answers

Not sure if there is something specific in underscrore.js to do this, but I'm sure it could be done in underscore syntax. However, you could do something like this in POJS.

Javascript

var testArray = [NaN, NaN, NaN, undefined, undefined, undefined, null, null, null, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1];

function is(x, y) {
    if (x === y) {
        if (x === 0) {
            return 1 / x === 1 / y;
        }

        return true;
    }

    var x1 = x,
        y1 = y;

    return x !== x1 && y !== y1;
}

function arraySplitToGroups(array) {
    var length = array.length,
        i = 0,
        newArray = [],
        subArray = [],
        current,
        last;

    while (i < length) {
        current = array[i];

        if (!is(last, current)) {
            if (subArray.length) {
                newArray.push(subArray);
            }

            subArray = [];
        }

        subArray.push(current);
        last = current;
        i += 1;
    }

    if (subArray.length) {
        newArray.push(subArray);
    }

    return newArray;
}

console.log(arraySplitToGroups(testArray));

Output

[ [NaN, NaN, NaN], [undefined, undefined, undefined], [null, null, null], [1, 1, 1], [2, 2, 2], [0, 0, 0], [1, 1, 1] ] 

On jsfiddle

UPDATE: Just as a pure interest thing, I took all the answers that were currently on the page a created a jsperf for them.

like image 97
Xotic750 Avatar answered Nov 21 '25 06:11

Xotic750


A plain old Javascript solution:

Fiddle

var original = [1,1,1,2,2,2,0,0,0,1,1,1];

var newArr = [], currentValue = null, currentArr;

if(original.length > 0){
    for(var i=0; i<original.length; i++){
        if(currentValue == null){
            currentValue = original[i];
            currentArr = [currentValue];
        } else {
            if(currentValue == original[i]){
                currentArr.push(currentValue);
            } else {
                newArr.push(currentArr);
                currentArr = [original[i]];
            }
        }
        currentValue = original[i];
    }
    newArr.push(currentArr);
}

Outputs:

[[1,1,1],[2,2,2],[0,0,0],[1,1,1]] 
like image 35
MrCode Avatar answered Nov 21 '25 05:11

MrCode



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!