【问题标题】:Split array into overlapping chunks (moving subgroups)将数组拆分为重叠的块(移动子组)
【发布时间】:2013-02-20 17:18:32
【问题描述】:

关于如何split a JavaScript array into chunks 有一个很好的问题。我目前正在将其用于我正在编写的一些统计方法,answer that I'm using 如下(尽管我选择不像他们在答案中那样扩展 Array 原型):

var chunk = function(array, chunkSize) {
    return [].concat.apply([],
        array.map(function(elem,i) {
            return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
        })
    );
};

这需要一个数组,例如[1,2,3,4,5,6],并给定一个chunkSize 2 返回[[1,2],[3,4],[5,6]]。我很好奇如何修改它以创建一组“重叠”块(或者对于那些熟悉诸如移动平均线、“移动子组”等方法的人)。

提供与上述相同的数组和 3 个 chunkSize,它将返回 [[1,2,3],[2,3,4],[3,4,5],[4,5,6]]chunkSize 为 2 将返回 [[1,2],[2,3],[3,4],[4,5],[5,6]]

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: javascript arrays splice moving-average


    【解决方案1】:
    function chunk (array, chunkSize) {
        var retArr = [];
        for (var i = 0; i < array.length - (chunkSize - 1); i++) {
            retArr.push(array.slice(i, i + chunkSize));
        }
        return retArr;
    }
    

    如果您确实想扩展原型(可能会更好),它看起来像这样:

    Array.prototype.chunk = function( chunkSize ) {
        var retArr = [];
        for (var i = 0; i < this.length - (chunkSize - 1); i++) {
            retArr.push( this.slice(i, i + chunkSize));
        }
        return retArr;
    }
    

    【讨论】:

    • 几件事:首先,您需要定义 var array = this; 以便在您的 for 循环中为原型扩展使用它。其次,这非常接近,但并不完全。给定[1,2,3,4,5,6],它返回[[1,2],[2,3],[3,4],[4,5]]。将i 的最大值从array.length - chunkSize 更改为array.length - chunkSize/2 解决了这个问题。谢谢!
    • 你在这两个方面都是对的......对不起,我没有花很长时间校对我的工作
    • 实际上重新考虑 array.length - chunkSize/2 不会工作。我想你会想要array.length - (chunkSize - 1)
    • 确认!是的。很好的捕获(我使用 2 的块大小来测试......)。再次感谢!
    • ES6 版本:const movingSubgroups = ([...array], chunkSize = 2) =&gt; { chunkSize = Math.min(2 ** 32 - 1, Math.max(0, chunkSize)); return array.reduce((result, _element, index, currentArray) =&gt; { if(index &lt;= currentArray.length - chunkSize){ result.push(currentArray.slice(index, index + chunkSize)); } return result; }, []); };.
    【解决方案2】:

    使用更具声明性和简洁性 (IMO) 的方法。

    const data = [1,2,3,4,5,6];
    
    function getGroups(dataList, groupSize) {
      return dataList
        .slice(groupSize - 1)
        .map((_, index) => dataList.slice(index, index + groupSize));
    }
    console.log("2:", JSON.stringify(getGroups(data, 2)));
    console.log("3:", JSON.stringify(getGroups(data, 3)));

    首先,我从数组的开头删除元素的数量,因为输出中的元素数量会适当地减少。然后我遍历剩余的元素,将它们映射到适当的组。

    【讨论】:

      【解决方案3】:

      我对 javaScript 不是很擅长,但这在算法上很容易通过两个嵌套的 for 循环来实现。这是 C# 中的一个解决方案 - 您应该能够很容易地解决这个问题。

      这使用了不太理想的数据结构,除了算法本身之外的一切都是显而易见的。

      protected List<List<int>> Split(List<int> array, int chunkSize)
      {
          List<List<int>> result = new List<List<int>>();
      
          for (int i = 0; i < array.Count - chunkSize; i++)
          {
              List<int> temp = new List<int>();
              for (int j = i; j < i + chunkSize; j++)
              {
                  temp.Add(array[j]);
              }
              result.Add(temp);
          }
      
          return result;
      }
      

      【讨论】:

        猜你喜欢
        • 2021-10-22
        • 2022-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多