I have a method that merges keys and indexes from an array into an object.
I'm stuck with ways to compress this method, and I don't know what I can do to make it simpler.
Goal
- get an array of objects with keys
- return an object with a unique key and the matching indexes
Code (simplified)
const items = [
{
"key": 0
},
{
"key": 2
},
{
"key": 4
},
{
"key": 4
}
]
function mergeItems (items) {
const helperObj = {}
// loop over items
items.forEach((item, itemIdx) => {
const { key } = item
// got key in helper obj? push index
if (key in helperObj) {
helperObj[key].push(itemIdx)
} else {
// create new array and set index
helperObj[key] = [itemIdx]
}
});
return helperObj
}
console.log(mergeItems(items));
Expected output:
{
"0": [0],
"2": [1],
"4": [2,3]
}
Question
Is there a way to do this without creating a helper object?
1 Answer 1
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);
-
\$\begingroup\$ Thanks. Let me think about this and I will come back later! \$\endgroup\$wittgenstein– wittgenstein2023年01月23日 19:44:20 +00:00Commented Jan 23, 2023 at 19:44
You must log in to answer this question.
Explore related questions
See similar questions with these tags.
result. \$\endgroup\$