英文:
reactor zip two sources with conditions
问题
public static Flux<Tuple2<Integer, Integer>> match(Flux<Tuple2<Integer, Integer>> flux) {
return flux.filterWhen(pair -> {
Integer t1 = pair.getT1();
Integer t2 = pair.getT2();
return Flux.just(t1)
.zipWithValues(Flux.just(t2))
.isEmpty()
.map(isEmpty -> !isEmpty);
});
}
英文:
I have two sources of sorted integers: A and B.
And I need to zip the two sources into one the restriction: Only zip these items who exist both in A and B.
For example:
A is: 1 2 3 10 11 12 13 14
B is: 10 12 13 14 15 16
The reactor's zip
operator would generate (1,10),(2,12),(3,13),(10,14),(11,15),(12,16)
But I want to get this source: (10,10),(12,12),(13,13),(14,14)
I tried a zip
and match
approach below, but failed, because the first complete source will cause zip
operator too complete the result source, and thus left source integer unmatched.
public static Flux<Tuple2<Integer, Integer>> match(Flux<Tuple2<Integer, Integer>> flux) {
Tuple2<Integer, Integer> invalidValue = Tuples.of(0, 0);
return flux.compose(f -> f.map(new Function<Tuple2<Integer, Integer>, Tuple2<Integer, Integer>>() {
private final Queue<Integer> left = new ArrayDeque<>(); // here is a problem: when complete, left or right queue may still have some data.
private final Queue<Integer> right = new ArrayDeque<>();
@Override
public Tuple2<Integer, Integer> apply(Tuple2<Integer, Integer> pair) {
left.add(pair.getT1());
right.add(pair.getT2());
return tryMatch();
}
private Tuple2<Integer, Integer> tryMatch() {
if (left.isEmpty() || right.isEmpty()) {
return invalidValue;
}
Integer t1 = left.peek();
Integer t2 = right.peek();
if (t1.equals(t2)) {
left.poll();
right.poll();
return Tuples.of(t1, t2);
} else if (t1 < t2) {
Integer item = left.poll();
log.warn("not matched: {}", item);
return tryMatch();
} else {
Integer item = right.poll();
log.warn("not matched: {}", item);
return tryMatch();
}
}
})).filter(pair -> pair != invalidValue);
}
Could someone help me, tell me what operator can I use?
答案1
得分: 1
不需要自己进行映射,可以使用 join 和 filter 函数。
Flux<Integer> f1 = Flux.just(1, 2, 3, 10, 11, 12, 13, 14);
Flux<Integer> f2 = Flux.just(10, 12, 13, 14, 15, 16);
f1.join(f2, f -> Flux.never(), f -> Flux.never(), Tuples::of)
.filter(t -> t.getT1().equals(t.getT2()));
或者如果你想要一个函数:
public <T> Flux<Tuple2<T, T>> match(Flux<T> f1, Flux<T> f2) {
return f1.join(f2, f -> Flux.never(), f -> Flux.never(), Tuples::of)
.filter(t -> t.getT1().equals(t.getT2()));
}
英文:
No need to map it yourself you can use join and filter
Flux<Integer> f1 = Flux.just(1,2,3,10,11,12,13,14);
Flux<Integer> f2 = Flux.just(10,12,13,14,15,16);
f1.join(f2,f ->Flux.never(),f-> Flux.never(),Tuples::of)
.filter(t -> t.getT1().equals(t.getT2()));
Or if you want a function
public <T> Flux<Tuple2<T,T>> match(Flux<T> f1, Flux<T> f2){
return f1.join(f2,f ->Flux.never(),f-> Flux.never(),Tuples::of)
.filter(t -> t.getT1().equals(t.getT2()));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论