如何从复杂对象数组中获取一组唯一属性

时间:2017-12-11 16:58:32

标签: javascript arrays typescript ecmascript-6

我有一个类似于

的对象数组
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"]}
]

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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 :(得分:1)

也许会有一个更优雅的map-reduce解决方案。无论如何,这将是有效的,即使它很难看:

v1.0.901

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