2016-12-01 13 views
1

私はAngular2アプリケーションでFirebaseを使用してデータベースからデータを取得しています。入れ子になったタグのリストにユニークな値の配列を返すのが一番簡単ですか?私。私の例では、["Sport", "Adventure", "Music"]の2番目の「アドベンチャー」が返されます。Angular2で観測可能な配列を平らにする

{ 
"images": { 
    "image1": { 
     "path": "path", 
     "date": 43534532123, 
     "tags": { 
      0: "Sport", 
      1: "Adventure" 
     } 
    }, 
    "image2": { 
     "path": "path", 
     "date": 43534532123, 
     "tags": { 
      0: "Music", 
      1: "Adventure" 
     } 
    }    

} 

私はこのアプローチを試みたが、それは最初の画像のみ

return this.af.database.list('/photos/user') 
     .map(photos => photos.map(photo => photo.tags)) 
     .concatAll() 
     .distinct() 

から要素を分割するようだしかし、このアプローチは、正しい出力が得られるが、ユニークなタグの別の流れとしての代わりとして1つの配列

return this.af.database.list('/photos/user') 
     .map(photos => photos.map(photo => photo.tags)) 
     .mergeAll() 
     .mergeAll() 
     .distinct() 
+0

私の悪い、それは正直に言うと画像1と画像2 – user3642173

+0

されている必要がありますあなたはおそらくも、この...あなたの 'map'機能のための特別な観察可能な魔法がちょうどAPIからオブジェクトを取ることができます必要はありませんし、それをその配列に減らしてください。そのためのすべてのロジックは 'map'コールバックの中に入ることができます。観測可能なもの自体は、ストリームのデータではなく、データのストリームを操作するための操作です。微妙な違いですが、重要です。だからこそ、単にデータを処理できるのは 'map'のコールバックの中にあると思います。あなたは '明確な排出物を必要としません、あなたは変更するために実際のデータが必要です。 – aaronofleonard

+0

質問の質を向上させるには、観測可能な 'this.af.database.list( '/ photos/user')'の構造を明確にしてください。タイプとメンバを定義します。 –

答えて

2

UPDATE

元の回答では、それは個々のアイテムを持つストリームであると仮定しました。その後、OPはの写真のリストであることを明確にしました。この場合、Observable#reduceの代わりにArray#reduceを使用します。

return this.af.database.list('/photos/user') 
    .map(photos => photos.map(photo => photo.tags) 
     .reduce((allTags, current) => { 
      return allTags.concat(
       current.filter(item => allTags.indexOf(item) === -1)) 
     }, [])) 

ストリームで観察戻りユニークな個々の値を超える

distinct ORIGINAL ANSWER、しかし、我々はここにしたい演算子ではありません。すべてのタグをそれぞれ別個の値としてシーケンスを生成することは可能ですが、再度それらを再グループ化する必要があります。

代わりに、reduceを使用することができます。これは、配列対応物と非常によく似ています。初期値([])をとり、他の値を累積します。私たちは、各反復ごとに個別の値を持つリストを作成しました。 reduceの後には、ユニークなタグの配列があります。

.list()は、それが機能するためには観測可能な値を記入する必要があります。

return this.af.database.list('/photos/user') 
     .map(photos => photos.map(photo => photo.tags)) 
     .reduce((allTags, current) => { 
      return allTags.concat(
       current.filter(item => allTags.indexOf(item) === -1)) 
     }, []) 
+0

ありがとうございます。それは良い解決策のように見えるが、残念ながらそれは動作しません。 1)**プロパティに 'タイプに存在しない'という[**]というエラーが表示されます。また、私が結果を購読するとき、私は何の出力も得られません。 .list()が最初に完了していることを確認するにはどうすればよいですか? – user3642173

+1

re: 'includes'、ES2016から' lib:["es2016"] 'を' tsconfig.json'に追加してください。ポリフィルが必要な場合があります。私は、indexOf()を使用する答えを変更するだろうと思う –

+0

私は参照してください。リスト()については、ほとんどが完了する必要がありますか? – user3642173

関連する問題