2017-07-18 4 views
0

受信データのページングに基づいてImmutable.Mapを更新しようとしています。データ構造内にトップレベルのインデックスを作成しています。ImmutableJSマップの更新

[ 
    { 
    identifier: ADFASD, 
    tags: [ tag1, tag2] 
    }, { 
    identifier: GGHYX, 
    tags: [ tag2, tag3] 
    }, 
] 

望ましい結果

{ 
    taggedArticleList: { 
    tag1: [ADFASD], 
    tag2: [ADFASD, GGHYX], 
    tag3: [GGHYX], 
    } 
} 

(作品)私はリファクタリングだ現在のJS機能:

let taggedArticleList = {} 
action.data.response.results.map((article) => { 
    article.tags.map((tag) => { 
     let key = taggedArticleList[tag] || (taggedArticleList[tag] = []; 
     key.article.push(article.identifier) 
    }); 
}); 
return taggedArticleList 

そして

入ってくるデータは次のようになります私の現在のImmutableJSの試み:

.update('taggedArticleList', taggedArticleList => 
    Immutable.Map(
     Immutable.fromJS(action.data.response.results).map(
      article => 
       article.get('tags').map(
        tag => 
         [ 
          tag, 
          taggedArticleList.has('tag') 
           ? taggedArticleList.get(tag).push(article.get('identifier')) 
           : Immutable.List().push(article.get('identifier')) 
         ] 
       ) 
     ))) 

私のアプローチは、受信したデータ「記事」をマップし、「タグ」をマッピングし、既存のtaggedArticleListにキーがあるかどうかを確認することです。新しいImmutable.Listとそれを押してください。私はImmutable.Mapコンストラクタをハイジャックしようとしています。それは[key, value]型の構造体をデフォルトの方法として受け入れます。

返されるデータ構造によって、私は奇妙なtag<List>のキーとList[tag, List[identifier]]の返りの形を与えています。どんなアドバイスも感謝しています。

Data Structure

答えて

1

私は、入力データのセット全体が不変のリストであることを

  • すなわち、(あなたが試みた溶液中で暗示している)あなたの着信データでも不変であると仮定しています
  • 各記事は不変のマップであり、
  • 各タグのシリーズは不変のリストである

私の回答にはtaggedArticleListというキーは含まれていません。このレベルのオブジェクト階層はこの質問の複雑さを増やしたり、取り除いたりしません。私はそれがあなたの特定のユースケースにとって重要なのであなたがそれを含んでいたと仮定しますが、それはこの答えのための余分な混乱です。以下のコードで、すなわちjsMapreduce機能のアキュムレータが、正常 JavaScriptの地図オブジェクト、ない不変地図オブジェクトである

ノート、すなわちjsMapは変更可能です。この変更は、このソリューションが機能するために必要であり、元のデータの処理中に使用される単純な中間変数であり、最終的には変更不可能なデータに変換されるため、不変のデータを扱う原則に違反しません地図。

上記のとおり、このソリューションでは、受信データも不変であると想定しています。ただし、JavaScriptオブジェクトのデータが「通常」(変更可能)だった場合は、article.get('tags')article.tagsに変更し、article.get('identifier')article.identifierに変更してください。

const incoming = Immutable.List([ 
    Immutable.Map({ 
    identifier: 'ADFASD', 
    tags: Immutable.List([ 'tag1', 'tag2']) 
    }), 
    Immutable.Map({ 
    identifier: 'GGHYX', 
    tags: Immutable.List([ 'tag2', 'tag3']) 
    }), 
]); 

const updated = Immutable.Map(
    incoming.reduce((jsMap, article) => { 
     article.get('tags').forEach(tag => { 
      jsMap.set(tag, Immutable.List([ 
       ...(jsMap.has(tag) ? jsMap.get(tag) : []), 
       article.get('identifier') 
      ])); 
     }); 
     return jsMap; 
    }, new Map()) // NOTE: this is a regular JavaScript map, NOT an Immutable map 
); 

console.log(updated); 

// console output: Map { "tag1": List [ "ADFASD" ], "tag2": List [ "ADFASD", "GGHYX" ], "tag3": List [ "GGHYX" ] } 

ちょうどサイドノートとして、また、あなたのオリジナルのソリューションでは、本来の作業JavaScriptコードと非作業不変コードの両方が、私はあなたが最初に、にもかかわらず、誤っmapを使用していると思うことに注意してください場合は、最終的にあなたの希望する解決策を得る。 mapは、各要素が元の配列内の要素に対応する配列を返すことを意図した関数です。各要素を順番に取得するために使用していますが、その要素を使用して、その関数から何も返さずに他のデータを変更するだけです。実際には、ではなく、には、元の配列に対応する配列要素があります。実際には、結果は配列でさえありません。それはオブジェクト(より正確には、Map ...わかりますが、混乱します)です。このような場合は、mapの代わりにforEachのようなものを使用しているはずです。あなたのコードは今回は機能しましたが、このようにしてmap関数を使用すると、将来混乱/バグが発生する可能性があります。あなたが使った方法は違法ではなく、あなたが実証したように、働くことができます。しかし、それはどのようにmapが意図されたのではありません。ちょうど私があなたにそれについての頭をアップすると思った。

関連する問題