【问题标题】:How to get an array of unique properties from an array of complex objects如何从复杂对象数组中获取唯一属性数组
【发布时间】:2018-05-25 06:12:19
【问题描述】:

我有一个类似的对象数组

const array = [
{
    documentId: "document1",
    writers: [
        {
            name: "writer1", 
            date: "2017-12-11"
        },
        {
            name: "writer2", 
            date: "2017-12-11"
        }
    ]
},
{
    documentId: "document2",
    writers: [
        {
            name: "writer1", 
            date: "2017-12-11"
        },
        {
            name: "writer3", 
            date: "2017-12-11"
        }
    ]
},
{
    documentId: "document3",
    writers: [
        {
            name: "writer3", 
            date: "2017-12-11"
        },
        {
            name: "writer4", 
            date: "2017-12-11"
        }
    ]
},

我正在尝试提取所有唯一作者的姓名并将它们与他们编写的所有文档进行匹配,以便最终数组看起来像这样:

const finalArray = [
    {name: "writter1", documents: ["document1", "document2"]},
    {name: "writter2", documents: ["document1"]},
    {name: "writter3", documents: ["document2", "document3"]},
    {name: "writter4", documents: ["document3"]}
]

【问题讨论】:

  • 欢迎来到 SO。请包括尝试的解决方案、它们为什么不起作用以及预期的结果。这真的会帮助我们找出你的代码的问题。谢谢!

标签: javascript arrays typescript ecmascript-6


【解决方案1】:

您可以使用Map,它会获取所有姓名和相关文件。如果没有地图可用于名称,则创建一个新条目。

然后结束,获取地图的所有对象。

var array = [{ documentId: "document1", writers: [{ name: "writer1", date: "2017-12-11" }, { name: "writer2", date: "2017-12-11" }] }, { documentId: "document2", writers: [{ name: "writer1", date: "2017-12-11" }, { name: "writer3", date: "2017-12-11" }] }, { documentId: "document3", writers: [{ name: "writer3", date: "2017-12-11" }, { name: "writer4", date: "2017-12-11" }] }],
    map = new Map,
    result;

array.forEach(function (o) {
    o.writers.forEach(function ({ name }) {
        map.has(name) || map.set(name, { name, documents: [] });
        map.get(name).documents.push(o.documentId);
    });
});

result = Array.from(map.values());

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

【讨论】:

    【解决方案2】:

    您可以使用 Map 将 writer 作为键,然后在您的数组上调用 reduce 以将文档映射到 writer,然后在 Map 对象上调用 values()

    const ret = Array.from(array.reduce((acc, val) => {
      val.writers.forEach(({ name }) => {
        let w = acc.get(name) || { name: name, documents: [] };
        w.documents = w.documents.concat(val.documentId);
        acc.set(name, w);
      });
      return acc;
    }, new Map()).values());
    
    console.log(ret);
    

    【讨论】:

      【解决方案3】:

      也许会有更优雅的 map-reduce 解决方案。无论如何,即使它很丑,这也会起作用:

      const array = //your data
      var output = []
      for (let i = 0; i < array.length; i++)
          for (let k = 0; k < array[i].writers.length; k++) {
              let t = output.find(function(a){return array[i].writers[k].name === a.name})
              if (t)
                  t.documents.push(array[i].documentId)
              else
                  output.push({name: array[i].writers[k].name, documents: [array[i].documentId]})
        }
      console.log(output)
      

      https://jsfiddle.net/50oph5g4/1/

      【讨论】:

        猜你喜欢
        • 2017-01-07
        • 1970-01-01
        • 1970-01-01
        • 2018-12-05
        • 1970-01-01
        • 1970-01-01
        • 2019-10-20
        • 2020-09-15
        • 1970-01-01
        相关资源
        最近更新 更多