如何使用RxJS进行groupBy并在特定数组中获取结果?

时间:2018-12-24 10:44:37

标签: json angular rxjs

我有一个具有以下属性的对象:

{
    title: 'Test',
    places: [
      {
        id: 1,
        longitude: 48.8469511,
        latitute: 2.3077989,
        address: 'Pont de Bir-Hakeim',
        city: {name: 'Paris', id: 1}
      },
      {
        id: 2,
        longitude: 48.855225,
        latitute: 2.288048,
        address: 'Palais-Musée Galliera, 10 avenue Pierre-1er-de-Serbie',
        city: {name: 'Paris', id: 1}
      },
      {
        id: 3,
        longitude: 50.8283315,
        latitute: -115.2608429,
        address: 'Fortress Moutain',
        city: {name: 'Calgary', id: 2}
      }
    ]
}

这是我想要的结果:

[
  {
    id: 1,
    name: 'Paris'
  },
  {
    id: 2,
    name: 'Calgary'
  },
]

如何通过使用groupBy map reduce来实现? 这是我尝试过的:

   return from(movie.places).pipe(
      groupBy(place => place.city.name),
      mergeMap(place => place.pipe(map(obj => obj.city.name))),
      toArray()
   );

哪种产品:

['Paris', 'Paris', 'Calgary']

在我的脑海中,如何将groupBymapmergeMaptoArray一起使用还不清楚... 感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

source$.pipe(
  map(state => state.places), // transform your source object to list of places.
  // Transform your list of place by list of city, then reduce it for unduplicate it.
  map(state => state.map(e => e.city).reduce( ( acc, cur ) => [
    ...acc.filter( ( obj ) => obj.id !== cur.id ), cur
  ], [] ))
).subscribe(console.log);

我已分成两个不同的地图以保持代码清晰,如果愿意,您可以轻松地将其合并到单个地图中。

对于大量数据收集,此代码也不安全,如果要有效处理大型数据,请选择normalizr

live code

source for uniq array of object base from id

答案 1 :(得分:0)

我认为,只需使用 toArray, map, distinct 运算符,您就可以做到:

return from(movie.places).pipe(map(place => place.city), distinct(entry => entry.id),toArray());

Demo