如何使用.distinct通过一个对象属性的内容从一个数组中删除对象

如何使用.distinct通过一个对象属性的内容从一个数组中删除对象

问题描述:

我想了解我的用例的.distinct操作:通过用户输入如何使用.distinct通过一个对象属性的内容从一个数组中删除对象

我做的是一个国家的搜索并且只想在名为country的属性中仅显示具有特定内容的一个对象。

说明:

我有各种物体的内容的BehaviorSubject:

[ 
{id:1, country: "United Kingdom", city:"London"}, 
{id:2, country: "United Kingdom", city:"Manchester"}, 
{id:3, country: "Germany", city:"Berlin"}, 
... 
] 

类型的阵列的是例如loc[]

interface loc { 
    id: number; 
    country: string; 
    city: string; 
} 

这是过滤通过用户输入(在下面的代码中称为“查询”):

BehaviorSubject 
    .map(x => x.filter((l) => 
    l.country.toLowerCase().indexOf(query.toLowerCase()) > -1)) 

如果用户输入是'美国',我得到一个结果数组与两个对象。

要获取只有一个对象,我使用另一个.map来处理重复项(标准js代码以从数组中删除重复项)并返回一个只包含一个对象的数组。

  1. 如何使用.distinct删除阵列中的重复项?
  2. 如果你看第.mapx的类型是loc[]。我如何获得.map运算符中数组的项而不是数组类型?

在此先感谢

就像在rxjs一切:这里有很多方法,如何做到这一点 - 这是我会怎么做:

关于distinct:如所描述的docs,它带有一个可选的KeySelectors功能作为第一个参数,在这里你可以回报国家:

.distinct(entry => entry.country) 

下面是完整的例子:

const allEntries$ = Rx.Observable.from([ 
 
{id:1, country: "United Kingdom", city:"London"}, 
 
{id:2, country: "United Kingdom", city:"Manchester"}, 
 
{id:3, country: "Germany", city:"Berlin"} 
 
]) 
 
    .publishReplay() 
 
    .refCount(); 
 

 
const userInput$ = new Rx.ReplaySubject(""); 
 
// just for demonstration-purposes 
 
userInput$.subscribe(input => console.log(">> Userinput: " + input)); 
 

 
// this is the important block 
 
const result$ = userInput$ 
 
    .switchMap(input => allEntries$ 
 
    .filter(forCountry(input)) 
 
    .distinct(byCountry) 
 
); 
 

 
// some helper for the filter, you could also do this inline, but it reads better this way 
 
function forCountry(country) { 
 
    country = country || ""; 
 
    coutnry = country.toLowerCase(); 
 
    return entry => entry.country.toLowerCase().indexOf(country) >= 0; 
 
} 
 

 
// some helper for the distinct, you could also do this inline, but it reads better this way 
 
function byCountry(entry) { 
 
    return entry.country; 
 
} 
 

 
// --- Simulation start 
 
result$.subscribe(result => console.log(">>>> Result: " + result.city)); // activate the stream 
 

 
userInput$.next("united"); 
 
userInput$.next("germ"); 
 
userInput$.next("e");
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

+0

感谢您的回答。当你有一个BehaviorSubject 而不是Observable.of 时,你将如何处理你的例子? – Mika

+0

这应该没有区别 - 唯一的一点是,如果BehaviorSubject更改的次数比userInput更快,那么'distinct'可能会有不同的行为 - 但是可以通过在当前switchMap中添加和附加级别来修复。 – olsn