Home > Net >  Assigning a grouped index within a javascript array
Assigning a grouped index within a javascript array

Time:10-15

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.

  • Related