Is there a way to do this in reduce()?

Elements in a flat array need to be paired into nested arrays. If there’s an uneven number of elements, the last one is put into a nested array by itself.

So [1, 2, 3, 4, 5, 6, 7, 8, 9] becomes [[1, 2], [3, 4], [5, 6], [7, 8], [9]]

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]

arr = arr.map((a, i) => i % 2 === 0 ? [a, arr[i + 1]] : null).filter(Boolean).map(a => a.filter(Boolean))

While this achieves the goal, I’m using 4 loops for something I feel can be solved in a simpler, more efficient way. Is there a way to do this in reduce() or some other method?

Honestly, this would probably be simplest with a traditional for loop. reduce() is really designed to turn an array into a single value, so trying to use it this way might just be more confusing.

But yeah, you could do it.

Can you please show me how?

I’m not going to write code for you, but I’d be happy to help you troubleshoot your own code.

I agree with @ArielLeslie . However if you want to practice array methods, you can use reduce. The purpose of map method is to return the same number of elements as the original, but ‘mapped’ to other value.

If you are facing difficulties with the loops, you should focus on that first IMO.

Hi @Montin.

Is there a way to do this in reduce() or some other method?

You can use recursion. A naive solution using recursion (there is probably a better way to do this) is:

const pairsRecursion =  arr => {
  if(arr.length === 0)  return [];
  if(arr.length === 1)  return [arr];

  if(arr.length >= 2 ) { 
    const  [  first, second,  ...rest] = arr;
    return [ [first, second] ].concat(pairsRecursion(rest))
  }
}


const a = [];
const b = [1];
const c = [1, 2];
const d = [1, 2, 3];
const e = [1, 2, 3, 4, 5, 6, 7, 8];
const f = [1, 2, 3, 4, 5, 6, 7, 8,9];


console.log("a: ", pairsRecursion(a));
console.log("b: ", pairsRecursion(b));
console.log("c: ", pairsRecursion(c));
console.log("d: ", pairsRecursion(d));
console.log("e: ", pairsRecursion(e));
console.log("f: ", pairsRecursion(f));

If we read reduce’s function signature ( Array.prototype.reduce() - JavaScript | MDN ):

reduce((accumulator, currentValue, currentIndex, array)

We can see that reduce uses:

  • an accumulator
  • currentIndex

And has access to:

  • The array
  • and his elements (currentValue).

So, we can try to write similar(similar, not equal to reduce) function:

const pairsRecursionAccumulator = (arr, acc=[], index=0) => {

  if(index >= arr.length) {
     return acc;
  }

// the same as your `i % 2 === 0`
  if(index % 2  === 0) {
   arr[index+1] !== undefined ? 
            acc.push([arr[index],arr[index+1]]) : 
            acc.push([arr[index]]) 
  } 
 
  return pairsRecursionAccumulator(arr, acc, index+1)
 
}

const a = [];
const b = [1];
const c = [1, 2];
const d = [1, 2, 3];
const e = [1, 2, 3, 4, 5, 6, 7, 8];
const f = [1, 2, 3, 4, 5, 6, 7, 8,9];

console.log("a: ", pairsRecursionAccumulator(a)); //  a:  []
console.log("b: ", pairsRecursionAccumulator(b)); //  b:  [ [ 1 ] ]
console.log("c: ", pairsRecursionAccumulator(c)); //  c:  [ [ 1, 2 ] ]
console.log("d: ", pairsRecursionAccumulator(d)); //  d:  [ [ 1, 2 ], [ 3 ] ]
console.log("e: ", pairsRecursionAccumulator(e)); //  e:  [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]
console.log("f: ", pairsRecursionAccumulator(f)); //  f:  [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ], [ 9 ] ]

Obviously, using reduce will be simpler.

1 Like

Seems to work.

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const size = 2;

const nestedArray = numbers.reduce((array, number, index) => {
  if (index % size === 0) {
    array.push([number]);
  } else {
    array[array.length - 1].push(number);
  }
  return array;
}, []);

console.log(nestedArray); // [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.