Is there a way to do this without creating a helper object?
It may be possible. Perhaps what you are really asking is whether there is a way to have a pure function, such that helperObj
does not need to be declared outside the callback function and modified within the callback function before it is utilized after the forEach
method is called. The callback functions passed to the forEach
method typically end up not being pure for this reason.
Instead of using the forEach()
method, the reduce()
method can be used. It still may have a helperObj
for the accumulator
argument but the scope is limited to within the callback function.
const items = [{ "key": 0 }, { "key": 2 }, { "key": 4 }, { "key": 4 } ] const mergedItems = items.reduce(function(helperObj, { key }, index) { if (helperObj[key]) { helperObj[key].push(index); } else { helperObj[key] = [index]; } return helperObj; }, {}); console.log('merged items: ', mergedItems);
Instead of either pushing or assigning to an array the array could be created when it does not exist:
const items = [{ "key": 0 }, { "key": 2 }, { "key": 4 }, { "key": 4 } ] const mergedItems = items.reduce(function(helperObj, { key }, index) { if (!helperObj[key]) { helperObj[key] = []; } helperObj[key].push(index); return helperObj; }, {}); console.log('merged items: ', mergedItems);
And if the goal is to greatly simplify it, a ternary operator could be used to compress it even further:
const items = [{ "key": 0 }, { "key": 2 }, { "key": 4 }, { "key": 4 } ] const mergedItems = items.reduce((acc, { key }, index) => { acc[index] ? acc[index].push(key) : acc[index] = [key]; return acc}, {}) console.log('merged items: ', mergedItems);
result
.\$\endgroup\$