-2

I have an array of objects. I want to group the objects by a value and then use that value as a key for the rest of the values in that object.

For example I have array like this:

{
  0: {prize: "Foo", first_name: "John", last_name: "Smith"},
  1: {prize: "Foo", first_name: "Mary", last_name: "Smith"},
  2: {prize: "Bar", first_name: "Jane", last_name: "Doe"},
  3: {prize: "Bar", first_name: "Jack", last_name: "Jones"},
  4: {prize: "Foo", first_name: "Judy", last_name: "Alvarez"},
}

And my desired outcome is something like this:

{
  Foo: [
   {first_name: "John", last_name: "Smith"},
   {first_name: "Mary", last_name: "Smith"},
   {first_name: "Judy", last_name: "Alvarez"}
  ],
  Bar: [
   {first_name: "Jane", last_name: "Doe"}, 
   {first_name: "Jack", last_name: "Jones"}
  ]
}

I'm using TypeScript and the closest I got was using this code snippet I found:

console.log(
  _.chain(res.data)
  .groupBy("prize")
  .map((value: any, key: any) => ({prize: key, winners: value}))
  .value()
);

Which gave me an outcome like this:

[
  0: {
      prize: "Foo", 
      winners: [
       {prize: "Foo", first_name: "John", last_name: "Smith"}, 
       {prize: "Foo", first_name: "Mary", last_name: "Smith"},
       {prize: "Foo", first_name: "Judy", last_name: "Alvarez"}
      ]
     },
  1: {
      prize: "Bar", 
      winners: [
       {prize: "Bar", first_name: "Jane", last_name: "Doe"}, 
       {prize: "Bar", first_name: "Jack", last_name: "Jones"}
      ]
     },
]

How would I modify my code to achieve the format I need effectively? I'm not even completely sure I'm on the right track, maybe the code needs to be completely changed?

This seems like a quite common problem and has probably been answered before but because I have a hard time even describing what I want, I couldn't find anything. I'm sorry if this is a duplicate.

ReynaMoon
  • 171
  • 1
  • 12
  • See also: https://stackoverflow.com/q/14446511, https://stackoverflow.com/q/40774697, https://stackoverflow.com/q/51852427, https://stackoverflow.com/q/36955906. – Aplet123 Dec 18 '20 at 14:39

2 Answers2

2

You could destructure the object and group by prize in a single loop.

const
    data = [{ prize: "Foo", first_name: "John", last_name: "Smith" }, { prize: "Foo", first_name: "Mary", last_name: "Smith" }, { prize: "Bar", first_name: "Jane", last_name: "Doe" }, { prize: "Bar", first_name: "Jack", last_name: "Jones" }, { prize: "Foo", first_name: "Judy", last_name: "Alvarez" }],
    result =  data.reduce(
        (r, { prize, ...rest }) => ((r[prize] ??= []).push(rest), r),
        {}
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
-1

You can loop through the original object using for...in and since you're using the prize property as the new key for the new object you can store the object (that will be put in the key's array) as a variable called t and store the key as a variable k.

 var k = obj[i].prize
 var t = obj[i]

See the snippet below for a working example.

var obj = {
  0: {prize: "Foo", first_name: "John", last_name: "Smith"},
  1: {prize: "Foo", first_name: "Mary", last_name: "Smith"},
  2: {prize: "Bar", first_name: "Jane", last_name: "Doe"},
  3: {prize: "Bar", first_name: "Jack", last_name: "Jones"},
  4: {prize: "Foo", first_name: "Judy", last_name: "Alvarez"},
}

const constructObj = () =>{
  var newObj = {}
  
  for (var i in obj){
    var k = obj[i].prize
    var t = obj[i]
    //remove below line to include all keys
    delete t.prize
    if (newObj[k]){
      var vals = newObj[k]
      vals.push(t)
    } else {
      newObj[k] = [t]
    }
  }
  return newObj
};

var final = constructObj()

console.log(final)
Matt Croak
  • 2,788
  • 2
  • 17
  • 35
  • This is much longer and frankly uglier than a lot of the code presented in the answers to the duplicates. – Aplet123 Dec 18 '20 at 14:39
  • @Aplet123 I was writing the answer when you commented and did not see them. If there is a better answer so be it but I don't think it warrants a downvote since the question itself was structured well, had all pertinent information included (including code snippet) and provided a feasible solution. – Matt Croak Dec 18 '20 at 14:41