How would I assign an index to each object within a group in an array using javascript. So starting at zero and counting up inside each group, ordered by the group then the id.
Starting with this
let data = [
{ "id": "AB", "name": "Fred", "group": 1},
{ "id": "BC", "name": "Jane", "group": 2 },
{ "id": "CD", "name": "Mary", "group": 1 },
{ "id": "DE", "name": "Bob", "group": 2 },
{ "id": "EF", "name": "Chris", "group": 1 },
{ "id": "FG", "name": "Steve", "group": 2 },
{ "id": "GH", "name": "Jim", "group": 2 }
]
But adding the groupIndex field for each object.
dataGrouped = [
{ "id": "DE", "name": "Bob", "group": 2, "groupIndex": 1 },
{ "id": "EF", "name": "Chris", "group": 1, "groupIndex": 2 },
{ "id": "BC", "name": "Jane", "group": 2, "groupIndex": 0 },
{ "id": "FG", "name": "Steve", "group": 2, "groupIndex": 2 },
{ "id": "AB", "name": "Fred", "group": 1, "groupIndex": 0},
{ "id": "CD", "name": "Mary", "group": 1, "groupIndex": 1 },
{ "id": "GH", "name": "Jim", "group": 2, "groupIndex": 3 }
]
CodePudding user response:
You could take an object for the indices.
const
indices = {},
data = [{ id: "AB", name: "Fred", group: 1 }, { id: "BC", name: "Jane", group: 2 }, { id: "CD", name: "Mary", group: 1 }, { id: "DE", name: "Bob", group: 2 }, { id: "EF", name: "Chris", group: 1 }, { id: "FG", name: "Steve", group: 2 }, { id: "GH", name: "Jim", group: 2 }],
result = data.map(o => {
indices[o.group] ??= 0;
return { ...o, groupIndex: indices[o.group] };
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
Presented below is one possible way to achieve the desired objective (viz, assigning group index to array elements). This solution does not address: "ordered by the group then the id."
Code Snippet
// method to assign group-index
// the resulting array may get ordered based on group & group-index (ascending)
const assignGroupIndex = arr => (
Object.values(
arr?.reduce(
(acc, { group, ...rest }) => {
if (!(group in acc)) acc[group] = [];
acc[group].push({
group, ...rest, groupIndex: acc[group].length,
});
return acc;
},
{}
)
).flat()
);
/*
// method to assign group-index for each elt in array
const assignGroupIndex = arr => ( // arg "arr" is the input array
// extract the values from the intermediate result object generated below
Object.values(
// use ".reduce()" to iterate the array and generate an intermediate result
arr?.reduce(
// "acc" is the accumulator, destructure to access "group" & other props
(acc, { group, ...rest }) => {
// if "group" not already in accumulator, set the value as empty array
if (!(group in acc)) acc[group] = [];
// push to the array a new object with "groupIndex" as current length
acc[group].push({
group, ...rest, groupIndex: acc[group].length,
});
// always return the accumulator for each iteration of ".reduce()"
return acc;
},
{} // "acc" - the accumulator is initialized as empty object
)
).flat() // use ".flat()" to remove nested arrays from Object.values()
);
*/
let data = [
{ "id": "AB", "name": "Fred", "group": 1},
{ "id": "BC", "name": "Jane", "group": 2 },
{ "id": "CD", "name": "Mary", "group": 1 },
{ "id": "DE", "name": "Bob", "group": 2 },
{ "id": "EF", "name": "Chris", "group": 1 },
{ "id": "FG", "name": "Steve", "group": 2 },
{ "id": "GH", "name": "Jim", "group": 2 }
];
console.log(
'assigned group-index to array:\n',
assignGroupIndex(data)
);
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added to the snippet above.