-2

How could I split an array by value like this:

[0, 1, 2, 0, 0, 0, 1, 0] => [[0, 1, 2], [0], [0], [0, 1], [0]]?

I'm using lodash documentary, but kinda out of ideas for now. Is there any way to do this with _.groupBy? Thanks for your answers.

6
  • Split based on consecutivity? Commented Jun 22, 2017 at 17:19
  • Is there a pattern that you want it to be split on? Commented Jun 22, 2017 at 17:20
  • @AndrewLi it do not seem consecutivity, it appears that you have to split whenever you encounter a 0 to me. Otherwise the first result element should be [0, 1, 2, 0] Commented Jun 22, 2017 at 17:27
  • @Eineki No, 2 doesn't come after 0 consecutively... Commented Jun 22, 2017 at 17:29
  • Is this one [0, 1, 2, 0, 0, 0, 1, 0, 2, 3, 4, 1, 2, 0, 0, 1] a valid input ? Commented Jun 22, 2017 at 17:38

4 Answers 4

4

Use native JavaScrip Array#reduce method.

var data = [0, 1, 2, 0, 0, 0, 1, 0],
  last;

var res = data.reduce(function(arr, v) {
  // check the difference between last value and current 
  // value is 1
  if (v - last == 1)
    // if 1 then push the value into the last array element
    arr[arr.length - 1].push(v)
  else
    // else push it as a new array element
    arr.push([v]);
  // update the last element value
  last = v;
  // return the array refernece
  return arr;
  // set initial value as empty array
}, [])

console.log(res);

Sign up to request clarification or add additional context in comments.

Comments

1

Below is succinct solution in ES2015 (formerly ES6).

const newArray = [];

[0, 1, 2, 0, 0, 0, 1, 0].forEach(item => item === 0 ?
    newArray.push([0]) :
    newArray[newArray.length - 1].push(item)
);

console.log(newArray);

Comments

1

If you have to start a new array when you encounter a zero you can resort to this code, hope it is not appear as vodoo programming.

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

x.join("")            /* convert the array to a string */
 .match(/(0[^0]*)/g)   /* use a regex to split the string 
                         into sequences starting with a zero
                         and running until you encounter 
                         another zero */
 .map(x=>x.split("")) /* get back the array splitting the 
                         string chars one by one */

I assume that the array elements are just a digit long and that 0 is the start of every sub array.

Removing the one digit assumption would resort to this code:

var x = [0, 1, 2, 0, 12, 0, 0, 1, 0];
var the_regexp = /0(,[1-9]\d*)*/g;

x.join(",")             /* convert the array to a comma separated  
                           string */
 .match(the_regexp)     /* this regex is slightly different from 
                           the previous one (see the note)  */
 .map(x=>x.split(","))  /* recreate the array */

In this solution we separate the array elements with a comma, Let's examine the regEx:

/0 means that every sub array starts with a 0, / is the beginning of the match

,[1-9]\d* this sub pattern match an the integer if it has a comma in front; the first digit cannot be 0, the other, optional, digits do not have this limitation. Thus we match ,1 or ,200 or ,9 or ,549302387439209.

We have to include in the subarray all the consecutive non zero number we find (,[1-9]\d*)* maybe none hence the second *.

`/g' closes the RegExp. The g indicates we want all the matches and not just the first one.

If you prefer an oneliner:

x.join(",").match(/0(,[1-9]\d*)*/g).map(x=>x.split(','));

or, if you prefer the pre ECMA2015 function expression syntax:

x.join(",").match(/0(,[1-9]\d*)*/g).map(function(x){return x.split(',');});

Comments

1

You could use a new array for every found zero value, otherwise append to the last array in the result set.

var array = [0, 1, 2, 0, 0, 0, 1, 0],
result = array.reduce(function (r, a) {
    if (a) {
        r[r.length - 1].push(a);
    } else {
        r.push([a]);
    }
    return r;
}, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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.