【问题标题】:From array choose one value to use as key and group by that value [duplicate]从数组中选择一个值作为键并按该值分组[重复]
【发布时间】:2021-03-29 05:05:03
【问题描述】:

我有一个对象数组。我想按一个值对对象进行分组,然后将该值用作该对象中其余值的键。

例如我有这样的数组:

{
  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"},
}

我想要的结果是这样的:

{
  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"}
  ]
}

我正在使用 TypeScript,我得到的最接近的是使用我发现的这段代码 sn-p:

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

这给了我这样的结果:

[
  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"}
      ]
     },
]

我将如何修改我的代码以有效地实现我需要的格式?我什至不完全确定我是否走在正确的轨道上,也许代码需要完全改变?

这似乎是一个很常见的问题,之前可能已经回答过,但是因为我什至很难描述我想要的东西,所以我找不到任何东西。如果这是重复的,我很抱歉。

【问题讨论】:

标签: javascript arrays json typescript lodash


【解决方案1】:

您可以在单个循环中按prize 解构对象和分组。

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; }

【讨论】:

    【解决方案2】:

    您可以使用for...in 遍历原始对象,并且由于您使用prize 属性作为新对象的新键,您可以将对象(将放入键的数组中)存储为名为t 的变量并将密钥存储为变量k

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

    请参阅下面的 sn-p 以获取工作示例。

    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)

    【讨论】:

    • 这比重复的答案中提供的许多代码要长得多,坦率地说也更丑。
    • @Aplet123 当您发表评论但没有看到它们时,我正在写答案。如果有更好的答案,那就这样吧,但我认为它不值得一票,因为问题本身结构良好,包含所有相关信息(包括代码 sn-p)并提供了可行的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2020-10-27
    • 2020-05-27
    • 2012-12-09
    • 2018-06-13
    • 1970-01-01
    • 2023-01-16
    • 2017-02-25
    • 2021-04-10
    相关资源
    最近更新 更多