There has been a discussion about whether or not we still need to use forEach
in JavaScript due to the availability of new language features. Some have suggested that this shift is an indirect push towards functional programming. I recently came across an array manipulation problem that required nested forEach
loops and I started thinking if there is a more functional way to solve it. While I was able to rewrite the code using reduce
, it turned out to be longer than the original forEach
solution. This made me question if there's a better approach to using functional programming to tackle this problem.
The challenge at hand is to transform an array of arrays into a flat array where each element is paired with the number of the sub-array it originated from. For example, convert [[8,2,4],[5],[1,7]]
into
[[8,0],[2,0],[4,0],[5,1],[1,2],[7,2]]
.
(To provide context for some of the initial comments on this question, the original emphasis was on reducing the code length. However, my real aim was to explore alternative solutions to this problem, which led to the revised question above.)
const oldArr = [[8,2,4],[5],[1,7]];
const newArr1 = [];
oldArr.forEach((subArr, subArrNum) => {
subArr.forEach(elmt => {newArr1.push([elmt, subArrNum]);});
});
const newArr2 = oldArr.reduce((accum1, subArr, subArrNum) => accum1.concat(
subArr.reduce((accum2, elmt) => accum2.concat([[elmt, subArrNum]]), [])
), []);
console.log(JSON.stringify(newArr1));
console.log(JSON.stringify(newArr2));
// To compare code length, here are the same solutions using single letter variable names compressed onto one line:
const o = oldArr;
let x,y;
x=[];o.forEach((s,n)=>{s.forEach(e=>{x.push([e,n]);});});
y=o.reduce((a,s,n)=>a.concat(s.reduce((b,e)=>b.concat([[e,n]]),[])),[]);
console.log(JSON.stringify(x));
console.log(JSON.stringify(y));