2017-12-11 1 views
1

私はすべてのユニークな作家の名前を抽出し、すべての文書にそれらを一致させるどのように複雑なオブジェクトの配列からユニークな特性の配列を取得するために

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"]} 
] 
+0

ようこそ。試行された解決策、失敗した理由、および予想される結果を含めてください。それは本当にあなたのコードの問題を理解するのに役立ちます。ありがとう! –

答えて

2

あなたはMapオブジェクトにvalues()を呼び出し、その後、作家に文書をマップするために、あなたのアレイ上reduceを呼び出して、キーとしての作家を保つために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

あなたはすべての名前と関連文書を取る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; }

1

たぶん、よりエレガントマップ-削減ソリューションが存在します。とにかく、この意志はそれは醜いだ場合でも動作します:

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/

関連する問題