【问题标题】:How to use .distinct to remove objects from an array via the content of a object property如何使用 .distinct 通过对象属性的内容从数组中删除对象
【发布时间】:2017-08-15 17:55:26
【问题描述】:

我想了解我的用例中的 .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 运算符中的数组项而不是数组类型?

提前致谢

【问题讨论】:

    标签: angular rxjs5


    【解决方案1】:

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

    关于distinct:如docs中所述,它以一个可选的keySelector-function作为第一个参数,在这里可以返回国家:

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

    【讨论】:

    • 感谢您的回答。当您有一个 BehaviorSubject 而不是 Observable.of 时,您将如何处理您的示例?
    • 这应该没有什么区别——唯一的是,如果 BehaviorSubject 比 userInput 更频繁地更改,distinct 的行为可能会有所不同——但这可以通过在当前添加和附加级别来解决切换地图。
    猜你喜欢
    • 2013-05-05
    • 2015-04-08
    • 2018-07-01
    • 2021-01-30
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2021-09-11
    相关资源
    最近更新 更多