【问题标题】:Diffing Two Arrays in RxJs在 RxJs 中区分两个数组
【发布时间】:2017-03-27 17:31:31
【问题描述】:

你以前见过这个问题,但我想了解这个问题在 RxJs 中的流程。

array1 = ["cat", "dog", "taco"]
array2 = ["cat", "dog", "fish"]

过滤 array2 以仅显示不在 array1 中的项目。预期结果:

result = ["fish"]

有效的方法: array1.map(value1 => array2 = array2.filter(value2 => value1 !== value2));

也许有更好的方法?

【问题讨论】:

  • 你说的是数组还是rxjs?在 Rxjs 中,基于另一个流过滤一个流的概念听起来很糟糕。如果它们只是数组,我会做array2.filter(value2 => !array1.includes(value2))
  • includes() 很棒,但我们的项目必须使用 IE 9 和 10。当然,this big, ugly polyfill 可用。我正在处理 Observables,而不是数组,但我想找到一种关系,因为 RxJs 为我们提供了一些相同(以及更多)的功能。感谢您的建议!
  • 否则你有 hack array1.indexOf(value2) >= 0,但这在某些极端情况下不起作用,比如处理我认为的对象

标签: javascript arrays rxjs


【解决方案1】:

你不需要 rxjs 来做差异。您可以使用任何提供差异功能的库。例如,如果您使用ramdadifference 运算符就是这样做的。参照。 http://ramdajs.com/docs/#difference

我相信underscore也存在同样的方法。

如果你想用 Rxjs 来做这件事,你就无法逃避 O(nm) 算法。使用给定库的特定算法可能会更幸运(例如,如果您有大数组要比较)。

【讨论】:

  • "但我想了解这个问题在 RxJs 中的流程。"
  • 对,但the flow of this question in Rxjs 没有意义。你不区分 rxjs 中的数组,你区分数组。在 rxjs 中,您处理流。所以如果你把你的问题变成一个关于流的问题,你将有更多的机会得到你可以使用的答案。
【解决方案2】:

你的意思是区分两个 observables 吗? 这是我的解决方案:

<html>
  <head>
    <title></title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.3.0/Rx.js"></script>
    <script>

    const observable_a =  Rx.Observable.interval(2000).take(10);//0,1,2,3,4,5,6,7,8,9
    const observable_b = Rx.Observable.interval(1000).map(x=>x+3).take(5);//3,4,5,6,7

    
    function observableDiff(a,b,filter) {
        if(!filter) {
            filter = (value_to_check,blacklist_array)=>{
                return blacklist_array.indexOf(value_to_check)===-1;
            };
        }
        return Rx.Observable.create(observer=>{
            let a_values = [];
            let b_values = [];
            let a_completed = false;
            let b_completed = false;
            
            a.forEach(a_value=>{
                if(b_completed) {
                    if(filter(a_value,b_values)) {
                        observer.next(a_value);
                    }
                } else {
                    a_values.push(a_value);
                }
            }).then(()=>{
                a_completed = true;
                if(b_completed) {
                    observer.complete();
                }
            });
            
            b.forEach(b_value=>{
                b_values.push(b_value);
            }).then(()=>{
                b_completed = true;
                a_values.forEach(a_value=>{
                    if(filter(a_value,b_values)) {
                        observer.next(a_value);
                    }
                });
                a_values = [];
                if(a_completed) {
                    observer.complete();
                }
            });
        });
    }
    
    observableDiff(observable_a,observable_b).subscribe(console.log);//0,1,2,8,9
    
    </script>
  </head>
  <body></body>
</html>

你也可以去这里寻找其他解决方案: Diffing two Observables

【讨论】:

  • 虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。
  • 嗨,我想为未来的读者指出,虽然这个算法可以很好地找到 A 中的哪些元素在 B 中不存在(如原始帖子中所要求的那样),但它不是完全差异,因为相反是不正确的。如果交换 observable_a 和 observable_b,因为 [3, 7] 元素范围包含在 [0, 9] 范围内,则根本不会发出任何内容。真正的 diff 要么需要两个不同的输出,要么需要一个具有不同属性的对象来识别每个中存在的内容,而另一个中不存在的内容(添加或删除的内容,在常见的差异意义上)。
  • @Stéphane Seyvoz 与您的定义匹配的真实差异需要等待两个可观察对象完成。这将破坏使用可观察对象而不是数组的目的
猜你喜欢
  • 2017-06-21
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-14
  • 1970-01-01
  • 2018-05-07
相关资源
最近更新 更多