Array splitting based on value

穿精又带淫゛_ 提交于 2019-12-13 09:10:02

问题


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.


回答1:


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);



回答2:


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; }



回答3:


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);



回答4:


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(',');});


来源:https://stackoverflow.com/questions/44705732/array-splitting-based-on-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!