nRxJava中的n元笛卡尔积

nRxJava中的n元笛卡尔积,java,math,rx-java,rx-java2,Java,Math,Rx Java,Rx Java2,现在我持有一个Observable以异步方式创建笛卡尔积是困难的,或者在某种意义上是不可能的。如果阻塞是可以的,你可以这样做 public class Main { static class ProductIterator<T> implements Iterator<T[]> { private final List<List<T>> componentsList; private final C

现在我持有一个
Observable以异步方式创建笛卡尔积是困难的,或者在某种意义上是不可能的。如果阻塞是可以的,你可以这样做

public class Main
{

    static class ProductIterator<T> implements Iterator<T[]>
    {
        private final List<List<T>> componentsList;
        private final Class<T> componentClass;
        private final int[] indices;
        private boolean hasNext;

        public ProductIterator(List<List<T>> componentsList, Class<T> componentClass)
        {
            this.componentsList = componentsList;
            this.componentClass = componentClass;
            this.indices = new int[componentsList.size()];
            this.hasNext = this.indices[componentsList.size() - 1] < componentsList.get(componentsList.size() - 1).size();
        }

        @Override
        public boolean hasNext()
        {
            return hasNext;
        }

        @Override
        public T[] next()
        {
            T[] res = (T[]) Array.newInstance(componentClass, componentsList.size());
            for (int i = 0; i < componentsList.size(); i++)
            {
                res[i] = componentsList.get(i).get(indices[i]);
            }

            // move next
            indices[0]++;
            for (int i = 0; i < componentsList.size() - 1; i++)
            {
                if (indices[i] == componentsList.get(i).size())
                {
                    indices[i] = 0;
                    indices[i + 1]++;
                }
            }
            hasNext = indices[componentsList.size() - 1] < componentsList.get(componentsList.size() - 1).size();

            return res;
        }
    }

    public static <T> Observable<T[]> product(Observable<Observable<T>> components, Class<T> componentClass)
    {
        return Observable.fromIterable(new Iterable<T[]>()
        {
            @Override
            public Iterator<T[]> iterator()
            {
                // postpone blocking up until iterator is requested 
                // and by this point we can't postpone anymore 
                Single<List<List<T>>> componentsList = components.map(o -> o.toList().blockingGet()).toList();
                return new ProductIterator<T>(componentsList.blockingGet(), componentClass);
            }
        });
    }

    public static void main(String[] args) throws Exception
    {
        Observable<Observable<Integer>> ob = Observable.just(
                Observable.just(0, 1),
                Observable.just(2, 3),
                Observable.just(4, 5)
        );

        Observable<Integer[]> product = product(ob, Integer.class);
        product.forEach(a -> System.out.println(Arrays.toString(a)));
    }
}
公共类主
{
静态类ProductIterator实现迭代器
{
私有最终列表组件列表;
私有final类componentClass;
私人最终综合指数;
私有布尔hasnet;
公共产品迭代器(列表组件列表,类组件类)
{
this.componentsList=componentsList;
this.componentClass=componentClass;
this.index=newint[componentsList.size()];
this.hasNext=this.index[componentsList.size()-1]o.toList().blockingGet()).toList();
返回新的ProductIterator(ComponentList.blockingGet(),componentClass);
}
});
}
公共静态void main(字符串[]args)引发异常
{
可观察的,可观察的(
可观测的。仅(0,1),
可观察。仅(2,3),
可观察。仅(4,5)
);
可观测产品=产品(ob,Integer.class);
product.forEach(a->System.out.println(Arrays.toString(a));
}
}

可以改进此代码以避免阻塞,但您仍然必须缓存所有
可观察的
的所有结果,代码将更加复杂。最有可能的是,阻塞对您来说是不可接受的,无论如何,尝试获得笛卡尔积是个坏主意。

好吧,我可以自己解决它。但是还有更优雅的方式吗?
(通过
toArray
方法将
可观察的
转换为
T[]

Observable to Observable阵列(Observable obs){
List List=obs.map(ob->toArray(ob)).toList().toblock().last();
返回Observable.create(新建SyncOnSubscribe()){
@凌驾
受保护的int[]生成属性(){
int[]数组=新的int[list.size()];
数组。填充(数组,0);
返回数组;
}
@凌驾

受保护的int[]下一步(int[]状态,Observer首先,您需要固定数量的输入
Observable
s。其次,不需要阻塞,但可能需要缓存,因为第二、第三个etc
Observable
s需要多次使用

import java.util.*;

import io.reactivex.Observable;

public class Cartesian {

    static Observable<int[]> cartesian(Observable<Observable<Integer>> sources) {
        return sources.toList().flatMapObservable(list -> cartesian(list));
    }

    static Observable<int[]> cartesian(List<Observable<Integer>> sources) {
        if (sources.size() == 0) {
            return Observable.<int[]>empty();
        }
        Observable<int[]> main = sources.get(0).map(v -> new int[] { v });

        for (int i = 1; i < sources.size(); i++) {
            int j = i;
            Observable<Integer> o = sources.get(i).cache();
            main = main.flatMap(v -> {
                return o.map(w -> {
                    int[] arr = Arrays.copyOf(v, j + 1);
                    arr[j] = w;
                    return arr;
                });
            });
        }

        return main;
    }

    public static void main(String[] args) {
        cartesian(Observable.just(
            Observable.just(0, 1), 
            Observable.just(2, 3), 
            Observable.just(4, 5)
        ))
        .subscribe(v -> System.out.println(Arrays.toString(v)));
    }
}
import java.util.*;
导入io.reactivex.Observable;
公共类笛卡尔{
静态可观测笛卡尔(可观测源){
返回sources.toList().flatMapObservable(列表->笛卡尔(列表));
}
静态可观测笛卡尔(列表源){
if(sources.size()==0){
return-Observable.empty();
}
可观测的main=sources.get(0.map)(v->newint[]{v});
对于(int i=1;i{
返回o.map(w->{
int[]arr=Arrays.copyOf(v,j+1);
arr[j]=w;
返回arr;
});
});
}
回水总管;
}
公共静态void main(字符串[]args){
笛卡尔(可观察到的(
可观测的。仅(0,1),
可观察。仅(2,3),
可观察。仅(4,5)
))
.subscribe(v->System.out.println(Arrays.toString(v));
}
}
    Observable<int[]> toObservableArray(Observable<Observable<Integer>> obs) {
        List<int[]> list = obs.map(ob -> toArray(ob)).toList().toBlocking().last();
        return Observable.create(new SyncOnSubscribe<int[], int[]>() {
            @Override
            protected int[] generateState() {
                int[] array = new int[list.size()];
                Arrays.fill(array, 0);
                return array;
            }

            @Override
            protected int[] next(int[] state, Observer<? super int[]> observer) {
                int[] next = new int[list.size()];
                for (int i = 0; i < next.length; i++) {
                    next[i] = list.get(i)[state[i]];
                }
                observer.onNext(next);
                state[state.length - 1]++;
                for (int i = state.length - 1; i >= 0; i--) {
                    int delta = list.get(i).length - state[i];
                    if (delta > 0) {
                        break;
                    } else if (delta == 0) {
                        state[i] = 0;
                        if (i == 0) {
                            observer.onCompleted();
                            break;
                        }
                        state[i - 1]++;
                    }
                }
                return state;
            }
        });
    }
import java.util.*;

import io.reactivex.Observable;

public class Cartesian {

    static Observable<int[]> cartesian(Observable<Observable<Integer>> sources) {
        return sources.toList().flatMapObservable(list -> cartesian(list));
    }

    static Observable<int[]> cartesian(List<Observable<Integer>> sources) {
        if (sources.size() == 0) {
            return Observable.<int[]>empty();
        }
        Observable<int[]> main = sources.get(0).map(v -> new int[] { v });

        for (int i = 1; i < sources.size(); i++) {
            int j = i;
            Observable<Integer> o = sources.get(i).cache();
            main = main.flatMap(v -> {
                return o.map(w -> {
                    int[] arr = Arrays.copyOf(v, j + 1);
                    arr[j] = w;
                    return arr;
                });
            });
        }

        return main;
    }

    public static void main(String[] args) {
        cartesian(Observable.just(
            Observable.just(0, 1), 
            Observable.just(2, 3), 
            Observable.just(4, 5)
        ))
        .subscribe(v -> System.out.println(Arrays.toString(v)));
    }
}