问题
I'm using the rxjs operators to handle the firebase observable lists. I need to sort distinct list based on the duplicated value (certain id).
this is my code:
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);
})
this is the log of (places.googleId)
so i need to sort this ids or the list according of the most duplicated number to be for example
1-Eg9MZWJhbm9uLCBCZWlydXQ
2-EhZIYW1yYSwgQmVpcnV0LCBMZWJhbm9u
3-ChIJR9lei8pAHxUREmilQojBkYc
Any help please,
thanks
回答1:
The basic approach that I would take is to reduce the array using a counter sort. I'm assuming that you want just one value at the end that represents the sorted result of the whole stream. So I added the last operator to wait for completion.
If you wanted to do this with RxJs then you could use the scan operator to reduce the stream and then sort it in a map operator.
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); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
Edit: You can use the reduce operator instead of .scan(...).last(). It basically does the same thing.
来源:https://stackoverflow.com/questions/48522124/how-to-sort-firebase-observable-list-based-on-the-duplicated-value-using-rxjs-op