admin管理员组

文章数量:1435859

I have an array

const myArray = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];

that I want to split into smaller arrays. I am using lodash chunk to do it.

_.chunk(myArray, 3);

this will return

[1, 2, 2], [2, 3, 3], [3, 4, 4], [4]

but I would like it to return

[1], [2, 2, 2], [3, 3, 3], [4, 4, 4]

my solution was this

_.chain(myArray).reverse().chunk(3).reverse().value()

it reverses the array, splits it and then reverses it again. But is there a better way to do this? So chunk starts from the end and not the start.

Runnable example:

const myArray = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];

console.log(_.chunk(myArray, 3));
  // => [1, 2, 2], [2, 3, 3], [3, 4, 4], [4]

console.log(_.chain(myArray).reverse().chunk(3).reverse().value());
  // => [1], [2, 2, 2], [3, 3, 3], [4, 4, 4]
<script src=".js/4.17.11/lodash.js"></script>

I have an array

const myArray = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];

that I want to split into smaller arrays. I am using lodash chunk to do it.

_.chunk(myArray, 3);

this will return

[1, 2, 2], [2, 3, 3], [3, 4, 4], [4]

but I would like it to return

[1], [2, 2, 2], [3, 3, 3], [4, 4, 4]

my solution was this

_.chain(myArray).reverse().chunk(3).reverse().value()

it reverses the array, splits it and then reverses it again. But is there a better way to do this? So chunk starts from the end and not the start.

Runnable example:

const myArray = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];

console.log(_.chunk(myArray, 3));
  // => [1, 2, 2], [2, 3, 3], [3, 4, 4], [4]

console.log(_.chain(myArray).reverse().chunk(3).reverse().value());
  // => [1], [2, 2, 2], [3, 3, 3], [4, 4, 4]
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Share Improve this question edited Feb 15 at 2:46 ggorlen 58.1k8 gold badges115 silver badges157 bronze badges asked Mar 8, 2019 at 0:12 DiarDiar 1432 silver badges9 bronze badges 3
  • Your reverse will probably also reverse the order of the items in each sub-array. You might not be seeing it because they're all the same value but you should probably check with more diverse data – Phil Commented Mar 8, 2019 at 0:17
  • Does the solution have to use Lodash or is vanilla JS also appropriate? – Phil Commented Mar 8, 2019 at 0:24
  • @Phil Hey. You're right. Now when I tested it with more diverse data it reverses the sub-arrays. The solution needs to use lodash but vanilla js is fine as long its not too much code. – Diar Commented Mar 8, 2019 at 0:30
Add a ment  | 

3 Answers 3

Reset to default 4

Find the remainder, and if there's remainder, slice it from the left side, and bine it with the chunks of the rest of the array. If no remainder, chunk normally:

const myArray = [1, 21, 22, 23, 31, 32, 33, 41, 42, 43];

const chunkRight = (arr, size) => {
  const rm = arr.length % size;
  
  return rm ?
    [arr.slice(0, rm), ..._.chunk(arr.slice(rm), size)]
    :
    _.chunk(arr, size);
};

const result = chunkRight(myArray, 3);

console.log(result);
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.11/lodash.js"></script>

There's no built-in argument option for that (or separate method like chunkEnd), but it's trivial to write something yourself that achieves the same thing without reverseing the array:

const chunkFromEnd = (arr, size) => {
  const firstSize = arr.length % size;
  const result = [arr.slice(0, firstSize)];
  
  for (let i = firstSize; i < arr.length; i += size) {
    result.push(arr.slice(i, i + size));
  }
  return result;
};
console.log(chunkFromEnd([1, 2, 2, 2, 3, 3, 3, 4, 4, 4], 3));
console.log(chunkFromEnd([1, 2, 2, 2, 3, 3, 3, 4, 9, 4, 4, 6, 2, 1], 3));

An alternative could be using the function reduceRight.

const myArray = [1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
const chunks = myArray.reduceRight((a, n, i, arr) => {
  if (((arr.length - 1) - i) % a.chunk === 0) {
    a.current = [];
    a.chunks.unshift(a.current);
  }
  
  a.current.push(n);  
  return a;
}, {
  /*This is the size per chunk*/chunk: 3, 
  /*The array with the chunks*/ chunks: [], 
  /*The current array which is being filled*/ current: []}).chunks;

console.log(chunks);
.as-console-wrapper { max-height: 100% !important; top: 0; }

本文标签: javascriptlodash chunk from end of arrayStack Overflow