代码之家  ›  专栏  ›  技术社区  ›  fweigl

对于列表中的每一项,执行操作直到满足条件

  •  4
  • fweigl  · 技术社区  · 6 年前

    void tryToOpenSafe() {
        getCorrectSafeCombination().subscribe(combination -> System.out.println("Correct combination is " + combination));
    }
    
    Maybe<Integer> getCorrectSafeCombination() {
        return getPossibleCombinations()
                .toObservable()
                .flatMapIterable(combinations -> combinations)
                .flatMap(combination -> tryToOpenSafeWithCombination(combination).toObservable()
                        .map(isCorrect -> new CombinationCheckResult(combination, isCorrect)))
                .filter(result -> result.isCorrect)
                .map(result -> result.combination)
                .firstElement();
    
    }
    
    Single<List<Integer>> getPossibleCombinations() {
        final List<Integer> combinations = Arrays.asList(123, 456, 789, 321);
        return Single.just(combinations);
    }
    
    // this is expensive
    final Single<Boolean> tryToOpenSafeWithCombination(int combination) {
        System.out.println("Trying to open safe with " + combination);
        final boolean isCorrectCombination = combination == 789;
        return Single.just(isCorrectCombination);
    }
    

    我收到一个可能的“组合”(整数)的列表,我想打开一个保险箱。当然,只有一个组合是正确的。

    以我目前的方法, getCorrectSafeCombination() 将提供它找到的第一个正确组合;但它仍将尝试所有组合。

    不过,这是有效的:只要找到正确的组合,就不需要尝试其他组合。

    如何使用Rx实现这一点?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Dmitry    6 年前

    这是因为 flatMap 用于在需要顺序的情况下并发处理观察值。要解决这个问题,你只需要改变你的想法 平面图 concatMap getCorrectSafeCombination 方法:

    Maybe<Integer> getCorrectSafeCombination() {
        return getPossibleCombinations()
                .toObservable()
                .flatMapIterable(combinations -> combinations)
                //this one
                .concatMap(combination -> tryToOpenSafeWithCombination(combination).toObservable()
                        .map(isCorrect -> new CombinationCheckResult(combination, isCorrect)))
                .filter(result -> result.isCorrect)
                .map(result -> result.combination)
                .firstElement();
    
    }