2017-05-28 5 views
2

異なるコレクションからデータを取得して1つのオブジェクト配列として返そうとしていますが、同じタイトルのオブジェクトをマージする必要があります。JS:同一のタイトル値を持つオブジェクトを新しい配列オブジェクトにマージする

'search': function(value) { 
    const res1 = Col1.find({ title: new RegExp(value, 'i') }, { fields: { title: 1, type: 1 } }).fetch() || [], 
      res2 = Col2.find({ title: new RegExp(value, 'i') }, { fields: { title: 1, type: 1 } }).fetch() || [] 

    let result = res1.concat(res2) 

    return result 
} 

は、最初のコレクションがtype -fieldのために私に「車」を与えると仮定し、第二は、「動物の私を与えます。

タイトルが同じ場合は、type -fieldを変更して内容を追加する必要があります。

{ _id: 1, title: 'mercedes', type: 'cars' } 
{ _id: 2, title: 'monkey', type: 'animals' } 
{ _id: 3, title: 'jaguar', type: 'cars' } 
{ _id: 4, title: 'jaguar', type: 'animals' } 

はあなたが同じタイトルのハッシュテーブルtitlesを使用して、配列にアイテムを割り当て、インデックスを救うことができる

{ _id: 1, title: 'mercedes', type: 'cars' } 
{ _id: 2, title: 'monkey', type: 'animals' } 
{ title: 'jaguar', type: 'multiple', results: [ 
    { _id: 3, title: 'jaguar', type: 'cars' } 
    { _id: 4, title: 'jaguar', type: 'animals' } 
] } 
+0

が見えますあなたのデータベースは最初とは異なっていますか? – adeneo

答えて

1

に変換する必要があります。

var data = [{ _id: 1, title: 'mercedes', type: 'cars' }, { _id: 2, title: 'monkey', type: 'animals' }, { _id: 3, title: 'jaguar', type: 'cars' }, { _id: 4, title: 'jaguar', type: 'animals' }], 
 
    result = data.reduce(function (titles) { 
 
     return function (r, a) { 
 
      if (titles[a.title]) { 
 
       if (titles[a.title].results.length === 1) { 
 
        r[titles[a.title].index] = { title: a.title, type: 'multiple', results: titles[a.title].results }; 
 
       } 
 
       titles[a.title].results.push(a); 
 
      } else { 
 
       titles[a.title] = { index: r.push(a) - 1, results: [a] }; 
 
      } 
 
      return r; 
 
     }; 
 
    }(Object.create(null)), []); 
 

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

あなたはクロージャの外にハッシュテーブルを移動することができます。

var data = [{ _id: 1, title: 'mercedes', type: 'cars' }, { _id: 2, title: 'monkey', type: 'animals' }, { _id: 3, title: 'jaguar', type: 'cars' }, { _id: 4, title: 'jaguar', type: 'animals' }], 
 
    titles = Object.create(null), 
 
    result = data.reduce(function (r, a) { 
 
     if (titles[a.title]) { 
 
      if (titles[a.title].results.length === 1) { 
 
       r[titles[a.title].index] = { title: a.title, type: 'multiple', results: titles[a.title].results }; 
 
      } 
 
      titles[a.title].results.push(a); 
 
     } else { 
 
      titles[a.title] = { index: r.push(a) - 1, results: [a] }; 
 
     } 
 
     return r; 
 
    }, []); 
 

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

+0

eslintは、data.reduce行の 'wrap-iife'エラーを表示します:http://eslint.org/docs/rules/wrap-iife私はこれを理解していません... – user3142695

+0

おそらく2番目のアプローチは合っていますeslint 。 –

+0

すごく、ありがとう。 – user3142695

0

あなたはタイトル毎にカウントし、各タイトルでfilterを使用して新しい配列を作成得ることができます:あなたが設定する必要がありますように

const a = [ 
 
    { _id: 1, title: 'mercedes', type: 'cars' }, 
 
    { _id: 2, title: 'monkey', type: 'animals' }, 
 
    { _id: 3, title: 'jaguar', type: 'cars' }, 
 
    { _id: 4, title: 'jaguar', type: 'animals' } 
 
], 
 
    titles = [...new Set(a.map(({title}) => title))] // count for each title 
 
    .map(t => Object.assign({[t]: a.filter(({title}) => title === t).length})) // current title count 
 
    .reduce((acc, v) => Object.assign(acc, v), {}); // form an object for convenience 
 
    
 
const res = Object.keys(titles) // for each title 
 
    .reduce((acc, t) => (titles[t] === 1) // if not multiple 
 
    ? acc.concat(a.filter(({title}) => title === t)) // add the element 
 
    : acc.concat(Object.assign({title: t, type: 'multiple', // form 'multiple' element 
 
    \t results: a.filter(({title}) => title === t)})) 
 
    , []) 
 
    
 
console.log(res)

関連する問題