将数组分成多组

3

我需要编写一个函数,将给定的数组(第一个参数)按指定长度(第二个参数)分组,并将它们作为二维数组返回。因此,chunkArrayInGroups(["a", "b", "c", "d"], 2) 应该返回 [["a", "b"], ["c", "d"]]。

function chunkArrayInGroups(arr, size) {
  // Break it up.
  var result=[];
  for (var i=0;i<=Math.ceil(arr.length/size);i++){

      var j=0;
      if(i!== 0){
        j+=size;
        size+=size;
      }

      result[i] = arr.slice(j , size);  

  }
  //return arr.length/size 
  //results in 1.5

return result;
// results [["a", "b"], ["c", "d"]]


}

chunkArrayInGroups(["a", "b", "c", "d"], 2);

我得到了期望的结果,但对我的解决方案不是很满意,更重要的是,“如果” arr.length = 4; 并且 size =2; 那么为什么 arr.length/size = 1 呢? 难道不应该是 4/2=2 吗?

原始数组arr没有受到影响,因为在result[i] = arr.slice(j, size);中使用了.slice()。需要改变原始数组吗?更重要的是,为什么arr.length = 4 - guest271314
9个回答

3
我建议将i改为在原始数组中开始每个组的索引进行迭代,而不是组的索引。
function chunkArrayInGroups(arr, size) {
  var result = [];
  for (var i=0; i<arr.length; i+=size)
    result.push(arr.slice(i, i+size));
  return result;
}

同时也考虑使用一个生成器:

function* chunkArrayInGroups(arr, size) {
  for (var i=0; i<arr.length; i+=size)
    yield arr.slice(i, i+size);
}

生成器是什么?还有,yield呢? 它可以与return交替使用吗? - user6050386

2

您在循环中修改了大小。这基本上会使大小每一步翻倍。您的示例只有两个子数组,因此隐藏了这个问题。尝试使用更大的数组以查看结果中的问题。

要解决此问题,请在循环外部声明j。在切片后将大小添加到j。

编辑:代码如下所请求

function chunkArrayInGroups(arr, size) {
  var result = [];
  var j = 0;
  for (var i = 0; i < Math.ceil(arr.length / size); i++) {
    result[i] = arr.slice(j, j + size);
    j = j + size;
  }
  return result;
}

或者,稍微简化一下:
function chunkArrayInGroups(arr, size) {
  let result = [];
  let pos = 0;
  while (pos < arr.length) {
    result.push(arr.slice(pos, pos + size));
    pos += size;
  }
  return result;
}

我在切片后如何给J增加大小?抱歉,我是新手! - user6050386
1
我认为 i <= Math.ceil(arr.length / size) 应该只是 '<' 而不是 '<='for (var i = 0; i < Math.ceil(arr.length / size); i++) - Santosh Sindham
@Santosh Sindham 谢谢,已修复。 - Stefan Haustein
感谢!请注意,第二个例子中第5行末尾缺少一个括号 - Perry
1
@Perry 谢谢,已修复! :) - Stefan Haustein

1
您可以使用slice()reduce()方法。

function chunkArrayInGroups(ar, num) {
  return ar.reduce(function(r, v, i) {
    if (i % num == 0) r.push(ar.slice(i, i + num));
    return r;
  }, []);
}

console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2))


1
以下解决方案非常有效:

function chunkv2(arr,size) {
    var result = [];
    for(var i = 0; i < arr.length; i++) {
        if(i%size === 0)
            // Push a new array containing the current value to the result array 
            result.push([arr[i]]);
        else
            // Push the current value to the current array
            result[result.length-1].push(arr[i]);
    }
    return result;

}

它通过使用模运算符来判断是否需要创建一个新数组。

0

我想没有比全面的减少解决方案更好的了,让我们开始吧;

var arr = ["a", "b", "c", "d"],
      g = 2,
    res = arr.reduce((p,c,i) =>  !(i%g) ? p.concat([[c]]) : (p[p.length-1].push(c),p),[]);
console.log(res);


0
更重要的是,为什么arr.length = 4?
由于在chunkArrayInGroups中使用了.slice(),原始数组arr不会受到影响。
result[i] = arr.slice(j , size)

@Rashid:“你觉得我的代码怎么样?很弱吗?”在原帖中没有以那种方式审查js。只是针对实际提出的问题审查了OP:“更重要的是为什么arr.length = 4”。 - guest271314
我觉得你误解了我的意思, 我的问题是,如果 arr.length = 4; 然后, size = 2; 那为什么 arr.length/size = 1.5?难道不应该是 4/2=2 吗? - user6050386
@Rashid:“那么为什么arr.length/size = 1.5?”你从哪里得到了“1.5”的值?在for循环中,size会随着size+=size;而改变。 - guest271314
@Rashid 不确定您是如何从 arr.length/size 获取值 1.5 的? - guest271314
抱歉,我的错。应该是1。 - user6050386

0

这是我想出来的:

function divyArray(input,size){
    var output = [];
    for(var i = 0;i<input.length;i){
        var chunk = [];
        for(var j = 0;j<size;j++){
            chunk.push(input[i]);
            i++;
        }
        output.push(chunk);
    }
    return output;
}

1
我的观点是你的处理过程太多了,对于大块数据,你正在做额外的工作。只需要尽可能地使用你创建的变量即可!在这里,我有输出、i、j和chunk。这样我就不需要做任何事情,只需要增加并测试大小或长度。 - Johnathan Ralls

0
简化它的方法可能看起来像这样:
    function chunkArrayInGroups(arr, size) {
    var result=[], j=0, divisions = arr.length/size;

    if (divisions % size != 0) { 
       console.log("Array of length"+ arr.length +"is undividable by "+divisions);
    }
    for (var i=0;i<=divisions-1;i++){
        result[i] = arr.slice(j , size);  console.log(result[i]);
        j+=size;
        size+=size;
    }
    return result;
}

你可能想为不可分割的数组添加一些错误逻辑,或者如果您想以不同的方式进行划分,则可以使用其他方法,但这与以前的方法非常接近,只是有一些变化。我不确定你是如何得到arr.length/size-1.5的结果的 - 我得到了正确的数字。


-1
你可以使用不带切片的方法。

function chunkArrayInGroups(array, size) {
    return array.reduce(function (r, a, i) {
        var p = Math.floor(i / size);
        r[p] = r[p] || [];
        r[p].push(a);
        return r;
    }, []);
}
  
console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接