【问题标题】:Array splitting based on value基于值的数组拆分
【发布时间】:2017-06-22 17:19:02
【问题描述】:

我怎样才能像这样按值拆分数组:

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

我正在使用 lodash 纪录片,但现在有点想法。有没有办法用_.groupBy 做到这一点? 感谢您的回答。

【问题讨论】:

  • 基于连续性拆分?
  • 是否有您想要拆分的模式?
  • @AndrewLi 似乎不是连续性的,看来你每次遇到 0 时都必须拆分。否则第一个结果元素应该是[0, 1, 2, 0]
  • @Eineki 不,2 不会连续出现在 0 之后...
  • 这是[0, 1, 2, 0, 0, 0, 1, 0, 2, 3, 4, 1, 2, 0, 0, 1] 的有效输入吗?

标签: javascript lodash


【解决方案1】:

使用原生 JavaScrip Array#reduce 方法。

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】:

    以下是 ES2015(以前的 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);

    【讨论】:

      【解决方案3】:

      如果您在遇到零时必须启动一个新数组,您可以求助于 这段代码,希望它不会像vodoo编程一样出现。

      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 */
      

      我假设数组元素只是一个数字长,0 是每个子数组的开始。

      删除一位数字的假设将诉诸此代码:

      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 */
      

      在这个解决方案中,我们用逗号分隔数组元素,让我们检查一下正则表达式:

      /0表示每个子数组都以0开头,/是匹配的开始

      ,[1-9]\d*这个子模式匹配一​​个整数,如果它前面有一个逗号;第一个数字不能为 0,其他可选数字没有此限制。因此我们匹配 ,1,200,9,549302387439209

      我们必须在子数组中包含我们找到的所有连续的非零数字 (,[1-9]\d*)* 可能没有,因此第二个 *

      `/g' 关闭正则表达式。 g 表示我们想要所有匹配项,而不仅仅是第一个匹配项。

      如果您更喜欢单线:

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

      或者,如果您更喜欢 ECMA2015 之前的函数表达式语法:

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

      【讨论】:

        【解决方案4】:

        您可以为每个找到的零值使用一个新数组,否则附加到结果集中的最后一个数组。

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

        【讨论】:

          猜你喜欢
          • 2012-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-20
          • 1970-01-01
          • 2016-12-31
          相关资源
          最近更新 更多