0

Extension of this question: using lodash .groupBy. how to add your own keys for grouped output?

Let's change the array to this one:

[
    {
        "name": "jim",
        "color": "blue",
        "order": 1,
        "age": "22"
    },
    {
        "name": "Sam",
        "color": "blue",
        "order": 1,
        "age": "33"
    },
    {
        "name": "eddie",
        "color": "green",
        "order": 3
        "age": "77"
    }
]

The order field has been added. In the previous question, this

var result = _.chain(data)
    .groupBy("color")
    .pairs()
    .map(function(currentItem) {
        return _.object(_.zip(["color", "users"], currentItem));
    })
    .value();
console.log(result);

was used to change the array into

[
    {
        color: "blue",
        users: [
            {
                "name": "jim",
                "color": "blue",
                "age": "22"
            },
            {
                "name": "Sam",
                "color": "blue",
                "age": "33"
            }
        ]
    },
    {
        color: "green",
        users: [
            {
                "name": "eddie",
                "color": "green",
                "age": "77"
            }
        ]
    }
]

Now, I want to add the "order" field to the group by such that the array looks like

[
    {
        color: "blue",
        order: 1,
        users: [
            {
                "name": "jim",
                "color": "blue",
                "age": "22"
            },
            {
                "name": "Sam",
                "color": "blue",
                "age": "33"
            }
        ]
    },
    {
        color: "green",
        order: 3,
        users: [
            {
                "name": "eddie",
                "color": "green",
                "age": "77"
            }
        ]
    }
]

2 Answers2

1

You could exclude order from the object with destructuring and taking the rest of the object.

const 
    data = [{ name: "jim", color: "blue", order: 1, age: "22" }, { name: "Sam", color: "blue", order: 1, age: "33" }, { name: "eddie", color: "green", order: 3, age: "77" }],
    result = _.chain(data)
        .groupBy("color")
        .map(users => ({
            color: users[0].color,
            order: users[0].order,
            users: users.map(({ order, ...o }) => o)
        }))
        .value();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

If you aren't determined to use lodash, this is actually really easy.

const data = [
    {
        "name": "jim",
        "color": "blue",
        "order": 1,
        "age": "22"
    },
    {
        "name": "Sam",
        "color": "blue",
        "order": 1,
        "age": "33"
    },
    {
        "name": "eddie",
        "color": "green",
        "order": 3,
        "age": "77"
    }
]

const result = data.reduce((carry, current) => {
    const { color, order, ...user } = current;
    let el = carry.find((item) => item.color === color && order === current.order);
    if (!el) {
         el = { color, order, users: [] }
         carry.push(el);
    }
    el.users.push({ ...user, color });
    return carry;
}, []);

console.log(result);
dave
  • 62,300
  • 5
  • 72
  • 93