【问题标题】:How to sort Firebase observable list based on the duplicated value using RXJS operators如何使用 RXJS 运算符根据重复值对 Firebase 可观察列表进行排序
【发布时间】:2018-07-09 09:07:20
【问题描述】:

我正在使用 rxjs 运算符来处理 firebase 可观察列表。 我需要根据重复值(特定 id)对不同的列表进行排序。

这是我的代码:

  this.places$
  .flatMap((x)=>{
    console.log(x)
    return x;
  })  
 .distinct((places:any)=>{ 
   console.log(places.googleId)
     return places.googleId;
  })
  .subscribe(snap=>{
    this.tempArray.push(snap);
  }) 

这是 (places.googleId) 的日志

所以我需要根据重复次数最多的数字对这个 id 或列表进行排序,例如

    1-Eg9MZWJhbm9uLCBCZWlydXQ 
    2-EhZIYW1yYSwgQmVpcnV0LCBMZWJhbm9u
    3-ChIJR9lei8pAHxUREmilQojBkYc

请帮忙,

谢谢

【问题讨论】:

  • 您希望它逐步排序还是仅在完成时对最终集进行排序?

标签: angular firebase-realtime-database ionic2 rxjs


【解决方案1】:

我将采取的基本方法是使用计数器排序来减少数组。我假设您最后只需要一个值来表示整个流的排序结果。所以我添加了last 操作符来等待完成。

如果您想使用 RxJs 执行此操作,则可以使用 scan 运算符来减少流,然后在 map 运算符中对其进行排序。

function countDistinct(map, current) {
  let entry = map.get(current.id);
  if (!entry) {
    entry = {
      count: 0,
      data: current
    };
    map.set(current.id, entry);
  }
  entry.count++;
  return map;
}

function sortCountDescending(a, b) {
    return a.count < b.count ? 1
      : a.count > b.count ? -1
      : 0;
}

Rx.Observable.of([
  { id: 1},
  { id: 2},
  { id: 3},
  { id: 2},
  { id: 2},
  { id: 3}
])
.flatMap(x => x)
.scan(countDistinct, new Map())
.last() // remove this if you want a progressive result
.map(x => Array.from(x.values()).sort(sortCountDescending).map(x => x.data))
.subscribe(x => { console.log(x); });
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"&gt;&lt;/script&gt;

编辑:您可以使用reduce 运算符代替.scan(...).last()。它基本上做同样的事情。

【讨论】:

  • ` this.places$ .flatMap((x)=>{ console.log(x) return x; }) .scan((map:any,current:any)=>{ let entry = map.get(current.googleId); if (!entry) { entry = { count: 0, data: current }; map.set(current.googleId, entry); } entry.count++; return map; }, new Map()) .map(x => Array.from(x.values()).sort((a:any,b:any)=>{ return a.count b.count ? -1 : 0; }).map((x:any) =>{ console.log(x); return x.data }) )`
  • 这是我的代码已格式化,我在订阅函数中未定义
  • 有时它会给出正确的列表有时未定义
  • @KhaledRamadan 您在 flatMap 运算符中的 console.log(x) 后面缺少一个分号。至少这是一个问题。
  • 为什么不用reduce而不是scan+last?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-02
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
相关资源
最近更新 更多