xavier.seignard
xavier.seignard

Reputation: 11144

From array to array of arrays

I'd like to transform an array like the following:

const myArray = [ 'a', 'b', 'c', 'd', 'e', 'f' ];

to something like this:

const transformedArray = [ [ 'a', 'b' ], [ 'c', 'd' ], [ 'e', 'f' ] ];

The only way I see is to do it with a good old for loop, but is there a more elegant way to do it with Array.prototype functions ?

Upvotes: 0

Views: 127

Answers (4)

Ori Drori
Ori Drori

Reputation: 191986

You can use Array.from() to create an array of chunks:

const myArray = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ];

const chunk = n => arr => 
  Array.from({ length: Math.ceil(arr.length / n) }, (_, i) =>
    myArray.slice(i * n, (i + 1) * n)
  );
  
const log = arr => console.log(JSON.stringify(arr));

log(chunk(2)(myArray)); // [["a","b"],["c","d"],["e","f"],["g"]]
log(chunk(3)(myArray)); // [["a","b","c"],["d","e","f"],["g"]]

Upvotes: 5

xavier.seignard
xavier.seignard

Reputation: 11144

One other solution that has been given to me which I find the most readable.

const myArray = [ 'a', 'b', 'c', 'd', 'e', 'f' ];
const transformedArray = Array(myArray.length / 2).fill().map((_, i) => [myArray[i * 2], myArray[i * 2 + 1]]);
console.log(transformedArray);

Upvotes: 0

OliverRadini
OliverRadini

Reputation: 6467

The solution below uses reduce to iterate over the items in the array. We use a modulo check on the index of the item to determine whether or not we need to start a new array.

The code adds in an object when it's inspecting an index which doesn't need to be formed into a new array. We later filter these objects out. There may be a more elegant way of doing this, but I feel it works out quite nicely.

const letters = [ 'a', 'b', 'c', 'd', 'e', 'f' ];

const splitIntoChunks = (arrayIn, size) => arrayIn.reduce(
  (prev, curr, i) => [
    ...prev,
    i % size === 0
       ? arrayIn.slice(i, i + size)
       : { '__remove': true }
  ],
  [],
).filter(x => !x['__remove'])

const result = splitIntoChunks(letters, 2)

console.dir(result)

Upvotes: 1

adiga
adiga

Reputation: 35222

You could do something like this using reduce, Math.floor and %

const myArray = ['a', 'b', 'c', 'd', 'e', 'f']

const newArray = myArray.reduce((acc, a, i) => {
  const index = Math.floor(i/2);
  acc[index] = acc[index] || [];
  acc[index][i % 2] = a
  return acc
}, [])

console.log(newArray)

  • Math.floor(i/2) gets which of the inner array the item belongs to
  • i % 2 gets which postion of the inner array the item belongs to

Upvotes: 5

Related Questions