Edited at

RxJava でズンドコキヨシ(window or buffer 使用)

More than 3 years have passed since last update.

調子に乗って RxJava でもやってみた。

がんばって Observable.window を使ってみた。


zondoko.java


// なんちゃってラムダ使用。あと Android。
public void doZondoko() {
final Random random = new Random();
final List<String> PATTERN = Arrays.asList("ずん", "ずん", "ずん", "ずん", "どこ");
final String K = "キ・ヨ・シ!";

Observable.concat( // ※ の Observable<List<String>> を直列に連結
Observable.interval(500, TimeUnit.MILLISECONDS)
.map(_ -> random.nextInt(2) == 0 ? "ずん" : "どこ") // ランダムに ずん or どこ
.window(PATTERN.size(), 1) // 要素数5のWindowを1ずつズラしてく
.map(window -> window.toList())) // Observable<Observable<String>> を Observable<List<String>> に変換 ※
.flatMap(window -> {
if (sequenceEqual(window, PATTERN)) { // パターンと一致していたら…
final List<String> says = new ArrayList<>();
says.addAll(window);
says.add(K); // キ・ヨ・シ!を追加
return Observable.concat(
Observable.just(says),
Observable.just(Collections.<String>emptyList())); // 終了判定用の空リスト
} else {
return Observable.just(window);
}
})
.takeWhile(says -> !says.isEmpty()) // 空リストになるまで繰り返す
.subscribe(says -> Log.d(TAG, dump(says)));
}

/** リストとリストの要素一致 */
private boolean sequenceEqual(List<String> listA, List<String> listB) {
Iterator<String> iterA = listA.iterator();
Iterator<String> iterB = listB.iterator();

while (iterA.hasNext() && iterB.hasNext()) {
if (iterA.next() != iterB.next()) {
return false;
}
}
return (!iterA.hasNext() && !iterB.hasNext());
}

/** リスト内容をダンプ */
private String dump(List<String> list) {
final StringBuilder b = new StringBuilder();
for (String s : list) {
if (!TextUtils.isEmpty(b.toString())) {
b.append(", ");
}
b.append(s);
}

return b.toString();
}



どこ, ずん, どこ, どこ, ずん

ずん, どこ, どこ, ずん, どこ

どこ, どこ, ずん, どこ, ずん

どこ, ずん, どこ, ずん, どこ

ずん, どこ, ずん, どこ, どこ

どこ, ずん, どこ, どこ, ずん

ずん, どこ, どこ, ずん, ずん

どこ, どこ, ずん, ずん, ずん

どこ, ずん, ずん, ずん, ずん

ずん, ずん, ずん, ずん, どこ, キ・ヨ・シ!


「window(5, 1) -> toList -> concat してるならそれは buffer(5, 1) やんけ」というのを こちら で知って、 buffer 版も書いてみた。


Zondoko_buffer.java

public void doZondoko() {

final Random random = new Random();
final List<String> PATTERN = Arrays.asList("ずん", "ずん", "ずん", "ずん", "どこ");
final String K = "キ・ヨ・シ!";

Observable.interval(500, TimeUnit.MILLISECONDS)
.map(_ -> random.nextInt(2) == 0 ? "ずん" : "どこ") // ランダムに ずん or どこ
.buffer(PATTERN.size(), 1) // 要素数5のBufferを1ずつズラしてく
.flatMap(buf -> {
if (sequenceEqual(buf, PATTERN)) { // パターンと一致していたら…
final List<String> says = new ArrayList<>();
says.addAll(buf);
says.add(K); // キ・ヨ・シ!を追加
return Observable.concat(
Observable.just(says),
Observable.just(Collections.<String>emptyList())); // 終了判定用の空リスト
} else {
return Observable.just(buf);
}
})
.takeWhile(says -> !says.isEmpty()) // 空リストになるまで繰り返す
.subscribe(says -> Log.d(TAG, dump(says)));
}