How to group together objects in an array with the same numerical value?

Viewed 30

I have an array of objects like so:

arrayOfObjects = [
    {
        "name": "OneFullValue",
        "value": 709
    },
    {
        "name": "DRTG",
        "value": 0
    },
    {
        "name": "OtherFullValue",
        "value": 345
    },
    {
        "name": "TYU",
        "value": 0
    },
    {
        "name": "TRHY",
        "value": 0
    },
    {
        "name": "UOI",
        "value": 0
    },
]

End goal:

arrayOfObjectsEndGoal = [
    {
        "name": "OneFullValue",
        "value": 709
    },
    {
        "name": "DRTG - TYU - TRHY - UOI",
        "value": 0
    },
    {
        "name": "OtherFullValue",
        "value": 345
    }
]

Essentially, I want to group together all of the objects with the same value where the "name" key has the value of all of the names of the other objects separated by a -.

NOTE: THE VALUE CAN BE ANY NUMBER OTHER THAN 0, FOR EXAMPLE, IF I HAVE AN ARRAY LIKE SO:

arrayOfObjects = [
    {
        "name": "OneFullValue",
        "value": 709
    },
    {
        "name": "DRTG",
        "value": 123
    },
    {
        "name": "OtherFullValue",
        "value": 345
    },
    {
        "name": "TYU",
        "value": 123
    },
    {
        "name": "TRHY",
        "value": 123
    },
    {
        "name": "UOI",
        "value": 123
    },
]

End goal (we're not multiplying 123 by how many objects there are with value 123, we're just equating it):

arrayOfObjectsEndGoal = [
    {
        "name": "OneFullValue",
        "value": 709
    },
    {
        "name": "DRTG - TYU - TRHY - UOI",
        "value": 123
    },
    {
        "name": "OtherFullValue",
        "value": 345
    }
]

I know how to combine all of the objects together

arrayOfObjects.reduce(
    ((prev, oth) => Object.assign(prev, oth)), {}
)

I also know that I can use a foreach to loop through the array and manipulate the values:

let objItem = {};
let arrayOfObjectsEndGoal = [];

arrayOfObjects.foreach((obj) => {
  if (objItem[obj.value]) {
    let first = objItem[obj.name] -1;
    let newValue = {
      ...arrayOfObjectsEndGoal[first]
    };

    arrayOfObjectsEndGoal[first] = newValue;
});

However, I'm unsure of how to move forwards to achieve the result. How can I combine objects like above?

1 Answers

You could add the names.

const
    data = [{ name: "OneFullValue", value: 709 }, { name: "DRTG", value: 0 }, { name: "OtherFullValue", value: 345 }, { name: "TYU", value: 0 }, { name: "TRHY", value: 0 }, { name: "UOI", value: 0 }],
    result = Object.values(data.reduce((r, { name, value }) => {
        r[value] ??= { name: '', value };
        r[value].name += (r[value].name && ' - ') + name;
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related