2

我有一个数组 [1,2,3,4,5,6,7 8,9,10,11,12,13]

我想把它分成小块,但大小不一样,我想每三个项目分块,然后一个,然后三个,依此类推。

以下代码将数组分块为三个大小

const chunk = (cards) => {
    var chunkArray = [];
    for(var i = 0; i < cards.length; i += 3) {
        chunkArray.push(cards.slice(i, i+3));
    }
    return chunkArray;
}
cards = [1,2,3,4,5,6,7,8,9,10,11,12,13];
console.log(JSON.stringify(chunk(cards)));

结果

[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11], [12, 13]]

我想要的结果

[[1, 2, 3, 4], [5], [6, 7, 8, 9], [10], [11, 12, 13]]

4

5 回答 5

2

在此处使用 while 循环,并添加一个名为 say chunksizes 的额外参数,然后您可以在每次迭代时对 chunksize 进行模数。

我也改用 while 循环,因为我认为它更适合这里,而不是使用 for 循环。

例如。

const test = [1,2,3,4,5,6,7,8,9,10,11,12,13];

const chunk = (cards, chunksizes) => {
  const chunkArray = [];
  let cc = 0, i = 0;
  while (i < cards.length) {
    const csize = chunksizes[cc];
    chunkArray.push(cards.slice(i, i + csize));
    cc = (cc + 1) % chunksizes.length;
    i += csize;
  }
  return chunkArray;
}

console.log(chunk(test, [4,1]));

于 2020-05-01T13:42:13.817 回答
2

chunk我会在一个更简单的可重用函数之上构建它,使用flatMap. 我们可以通过将五个一组的分组然后将结果分成四个一组来按这种模式进行分组。这个版本没有使用chunk可以想象到的最高效的,你可能想用一个迭代版本来替换它,但我认为它很好地展示了这个想法:

const chunk = (n) => (arr) => 
  arr .length ? [arr .slice (0, n), ... chunk (n) (arr .slice (n))] : []

const pattern4_1 = (xs) => chunk (5) (xs) .flatMap (chunk (4))

console .log(
  pattern4_1 ([1,2,3,4,5,6,7,8,9,10,11,12,13])
)

更新

以下是 的变体chunk,按效率递增顺序(猜测;我没有测试过)和优雅递减顺序(很明显):

const chunk = (n) => (xs) => 
  xs .length ? [xs .slice (0, n), ... chunk (n) (xs .slice (n))] : []

const chunk = (n) => (xs) => 
  xs .reduce ((res, x, i) => i % n == 0 
    ? [...res, [x]] 
    : [...res.slice(0, res.length - 1), [...res[res.length - 1], x]]
  , [])


const chunk = (n) => (xs) => 
  xs .reduce ((res, x, i) => {
    if (i % n == 0) {
      res.push([])
    }
    res[res.length - 1].push(x)
    return res
  }, [])

const chunk = (n) => (xs) => {
  const res = []
  let curr = []
  for (let i = 0; i < xs.length; i++) {
    if (i % n == 0 && i > 0) {
      res.push (curr)
      curr = []
    }
    curr.push(xs[i])
  }
  res.push (curr)
  return res
}

在优雅和效率之间进行这样的权衡通常是一种耻辱,但在 JS 中经常出现这种情况。

于 2020-05-01T13:42:50.337 回答
1

我会做这样的事情:

const chunk = (cards) => {
  var chunkArray = [];
  for(var i = 0; i < cards.length; i += 3) {
    if(i%2 == 0){var state = 3} //if its even
    else{state = 0} //if its odd
    chunkArray.push(cards.slice(i, i+=state));
  }
  return chunkArray;
}
于 2020-05-01T13:35:13.520 回答
0

在决定要切片多少之前检查索引:

const chunk = (cards) => {
  var chunkArray = [];
  let j = 0; i = 0;
  while (i < cards.length) {
    if (j % 2 == 0) {
       chunkArray.push(cards.slice(i, i + 4));
       i += 4;
    } else {
       chunkArray.push(cards.slice(i, i + 1));
       i++;
    }
    j++;
  }
  return chunkArray;
}

console.log(chunk([1,2,3,4,5,6,7,8,9,10,11,12,13]));

于 2020-05-01T13:36:06.900 回答
0

尝试 :

const arr = [1,2,3,4,5,6,7,8,9,10,11,12,13]

const chunk = (cards) => {
  var chunkArray = [];
  for(var i = 0; i < cards.length; i += 5) {
    chunkArray.push(cards.slice(i, i+4));
    if(i+4<cards.length)chunkArray.push(cards.slice(i+4, i+5));
    else break
  }
  return chunkArray;
}

console.log(chunk(arr))

于 2020-05-01T13:44:43.963 回答