RxJava中的笛卡尔积

16

在RxJava中是否有可能获得两个Observables的笛卡尔积?

类似于这样:

A -> 1,2,3
B -> a,b
A x B -> (1, a), (1, b), (2, a), (2, b), (3, a), (3, b)

所以,当 c 到达 B 时,A x B 会产生“c 与到目前为止到达 A 的元素相乘”的结果吗? - jhegedus
1
我的直觉(基于反应式课程)是可能的,但这只是一种感觉 :) 抱歉,我的 RX 有点生疏。 - jhegedus
1
第四周的材料可能有答案 https://www.coursera.org/course/reactive - jhegedus
3个回答

14

你想要的是为一个数字生成与字母数量相同的一对元素。 你可以使用mapflatMap操作符轻松实现此目标。

    Observable<Integer> number = Observable.from(Arrays.asList(1, 2, 3));
    Observable<String> letters = Observable.from(Arrays.asList("a", "b"));

    Observable<Pair> cartesian = number.flatMap((n) -> letters.map((l) -> new Pair(n, l)));

1
谢谢David,我正好遇到了这个需求;)但这是第一个版本,我需要一个计算可变大小的Observables列表的笛卡尔积的版本。更加棘手。 - Cédric Vidal
你可以采用这种方法,并在for循环中不断添加flatMap()。 - tmn
fun main(args: Array<String>) {val sources = listOf( Observable.just(1, 2, 3, 4, 5), Observable.just(10, 20, 30, 40, 50), Observable.just(100, 200, 300, 400, 500) ) var cartesianProduct: Observable>? = null for (obs in sources) { if (cartesianProduct == null) { cartesianProduct = obs.map { listOf(it) } } else { cartesianProduct = cartesianProduct.flatMap { list -> obs.map { list.plus(it) }} } } cartesianProduct!!.subscribe(::println)} - tmn

1
“join”不是你要找的吗?
    Observable<Integer> a = Observable.fromArray(1, 2, 3);
    Observable<String>  b = Observable.fromArray("a", "b");

    Observable<?> left  = Observable.never();
    Observable<?> right = Observable.never();

    Observable<Pair<Integer, String>> pairs = a.join(b, (aa)->left, (bb)->right, (ai, bi)-> Pair.of(ai, bi));

-1

这里是笛卡尔映射的伪代码。

A  ->  Pair<A,"letter">  ->  C
B  ->  Pair<B,"number">  ->  D

Merge(C,D) -> lift(new CartesianOperator) -> Result  

笛卡尔运算符将存储一组数字和一组字符。

如果引入了一个独特的字符,您需要为该独特字符与您记录的数字列表中的每个组合生成响应。然后将您的独特字符添加到字符列表中,然后重复此过程。

对于唯一的数字也是如此。

最终,您将能够发送类似于1,1,2,3和a,b,b,并接收类似于(a,1)(a,2)(a,3)(b,1)(b,2)(b,3)的内容。

编辑:

这里有一个快速且不可扩展的实现,它可以使用一对对象。

其中值1是您的'a'、'b'、'1'、'2'或'3',而值2是您的类型('number'或'character')。

它返回一个映射到数字的可观察字符对。

public class CartesianOperator implements Observable.Operator<Pair<String,String>,Pair<String,String>> {


@Override
public Subscriber<? super Pair<String, String>> call(final Subscriber<? super     Pair<String, String>> subscriber) {
return new Subscriber<Pair<String, String>>() {
  List<String> numbers;
  List<String> characters;
  @Override
  public void onCompleted() {

  }

  @Override
  public void onError(Throwable e) {

  }

  @Override
  public void onNext(Pair<String, String> stringStringPair) {

    if(stringStringPair.second == "number")
    {
      if(numbers.size() == 0)
      {
        numbers.add(stringStringPair.first);
      }
      else
      {
        if(numbers.contains(stringStringPair.first))
        {}
        else
        {
          for(String temp: characters)
          {
            //Return Every permutation of existing characters with new number
            subscriber.onNext( new Pair<String,String>(temp,stringStringPair.first));
          }
        }

      }
    }
    else // Assume vallue is a character
    {
      if(characters.size() == 0)
      {
        characters.add(stringStringPair.first);
      }
      else
      {
        if(characters.contains(stringStringPair.first))
        {}
        else
        {
          for(String temp: numbers)
          {
            //Return Every permutation of existing numbers with new character
            subscriber.onNext( new Pair<String,String>(stringStringPair.first,temp));
          }
        }
      } 
    }
  }
};
}
}

如果您不知道什么是配对对象,它实际上是一个封装了两个其他对象的对象。

pairObject.first  

返回我的一对中的第一个对象。
pairObject.second

返回我的一对中的第二个对象

我认为它现在已经过时了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接