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

How to use .distinct to remove objects from an array via the content of a object property

我想了解我用例中的 .distinct 运算符:

我通过用户输入搜索一个国家/地区,并且只想显示 属性 国家/地区中具有特定内容的一个对象。

解释:

我有一个包含各种对象内容的 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;
}

这是通过用户输入过滤(在下面的代码中称为 'query'):

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

如果用户输入 'United' 我得到一个包含两个对象的结果数组。

为了只获得一个对象,我使用另一个 .map 来处理重复项(标准 js 代码从数组中删除重复项)和 return 只有一个对象的数组。

  1. 如何使用 .distinct 删除数组中的重复项?
  2. 如果您查看第一个 .mapx 的类型是 loc[]。如何获取 .map 运算符中的数组项而不是数组类型?

提前致谢

就像 rxjs 中的所有内容一样:有很多方法,如何做到这一点 - 这就是我的做法:

关于distinct: As described in the docs,它采用可选的keySelector-function作为第一个参数,您可以在其中return国家:

.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>