0

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 ?

0

4 Answers 4

5

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
Sign up to request clarification or add additional context in comments.

Comments

5

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"]]

Comments

1

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)

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.