【问题标题】:Grouping objects in an array by multiple keys通过多个键对数组中的对象进行分组
【发布时间】:2018-02-20 09:16:08
【问题描述】:

最初,我有这个数组:

[{
    "vendorid": 1,
    "vendorname": "Vendor1",
    "maxfilelimit": 2,
    "uploadfilename": "Voice1.xlsx"
},
{
    "vendorid": 1,
    "vendorname": "Vendor1",
    "maxfilelimit": 2,
    "uploadfilename": "Ven1_Voice.xlsx"
},
{
    "vendorid": 2,
    "vendorname": "Vendor2",
    "maxfilelimit": 2,
    "uploadfilename": "Voice2.xlsx"
},
{
    "vendorid": 2,
    "vendorname": "Vendor2",
    "maxfilelimit": 2,
    "uploadfilename": "Ven2_Voice.xlsx"
}]

我希望数组中的文件名没有重复记录。因此,我希望输出类似于以下内容:

[{
    "vendorid": 1,
    "vendorname": "Vendor1",
    "maxfilelimit": 2,
    "uploadfilename": ["Voice1.xlsx", "Ven1_Voice.xlsx"]
}, {
    "vendorid": 2,
    "vendorname": "Vendor2",
    "maxfilelimit": 2,
    "uploadfilename": ["Voice2.xlsx", "Ven2_Voice.xlsx"]
}]

我找到了一些解决方案,例如 d3.js、alaSQL,但没有得到预期的输出

【问题讨论】:

  • array.reduce 是你的朋友。
  • 谢谢!你能解释一下我如何在我的场景中使用它吗?
  • 视情况而定。您的数据有哪些变化,哪些保持不变?当它改变时,什么是重要的。我可以看到你需要一个文件名数组......还有什么?
  • 您是说项目应该根据前三个字段中的所有三个字段都相同进行分组吗?可能有助于更新问题中的示例输入,使其在输出中包含多个记录。
  • 是的,你没看错!我不会。可能包含具有多个文件名的不同vendors 的记录。所以,我想对供应商的文件进行分组。其中vendoridvendornamemaxfilelimit 对于特定供应商是相同的。

标签: javascript alasql


【解决方案1】:

您可以使用array#reduce,在其中您可以将结果存储在一个对象中,然后使用Object.values() 提取值。

var data = [{"vendorid": 1,"vendorname": "Vendor1","maxfilelimit": 2,"uploadfilename": "Voice1.xlsx"},{"vendorid": 1,"vendorname": "Vendor1","maxfilelimit": 2,"uploadfilename": "Ven1_Voice.xlsx"},{"vendorid": 2,"vendorname": "Vendor2","maxfilelimit": 2,"uploadfilename": "Voice2.xlsx"},{"vendorid": 2,"vendorname": "Vendor2","maxfilelimit": 2,"uploadfilename": "Ven2_Voice.xlsx"}];

var result = data.reduce((hash, obj) => {
  let key = obj.vendorid+'|' +obj.vendorname+'|' +obj.maxfilelimit;
  if(hash[key])
      hash[key].uploadfilename.push(obj.uploadfilename);
  else {
      hash[key] = obj;
      hash[key].uploadfilename = [obj.uploadfilename];
    }
   return hash; 
},{});
console.log(Object.values(result));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:
    var data = [{
        "vendorid": 1,
        "vendorname": "Vendor1",
        "maxfilelimit": 2,
        "uploadfilename": "Voice1.xlsx"
    },
    {
        "vendorid": 1,
        "vendorname": "Vendor1",
        "maxfilelimit": 2,
        "uploadfilename": "Ven1_Voice.xlsx"
    },
    {
        "vendorid": 2,
        "vendorname": "Vendor2",
        "maxfilelimit": 2,
        "uploadfilename": "Voice2.xlsx"
    },
    {
        "vendorid": 2,
        "vendorname": "Vendor2",
        "maxfilelimit": 2,
        "uploadfilename": "Ven2_Voice.xlsx"
    }];
    ;
    // create lookup table
    let lookup = data.reduce((p, v) => {
        // seen me yet?
        if (p[v.vendorid]) {
        p[v.vendorid].uploadfilename.push(v.uploadfilename); 
      } else {
        // nope ... first time
        p[v.vendorid] = v;
        // create array of filenames
        p[v.vendorid].uploadfilename = [v.uploadfilename];
      }
      return p;
    }, {});
    
    // convert back to array
    Object.keys(lookup).map(key => lookup[key]);
    

    【讨论】:

      猜你喜欢
      • 2016-12-27
      • 2015-11-04
      • 2022-01-11
      • 2022-11-14
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 2016-04-30
      • 1970-01-01
      相关资源
      最近更新 更多