uniqAdjacent

바로 앞 원소와 같은 원소를 버립니다 — 인접한 중복만 사라지고, seen 집합은 쌓이지 않습니다.

Iterable<A> uniqAdjacent<A>(Iterable<A> iterable) Iterable<A> uniqAdjacentBy<A, B>(B Function(A a) f, Iterable<A> iterable) FxAsyncIterable<A> uniqAdjacentAsync<A>(FxAsyncIterable<A> iterable) FxAsyncIterable<A> uniqAdjacentByAsync<A, B>(FutureOr<B> Function(A a) f, FxAsyncIterable<A> iterable) Fx<T> Fx<T>.uniqAdjacent() / .uniqAdjacentBy<B>(B Function(T a) f) // chain (sync) FxAsync<T> FxAsync<T>.uniqAdjacent() / .uniqAdjacentBy<B>(FutureOr<B> Function(T a) f) // chain (async) FxEvents<T> FxEvents<T>.uniqAdjacent() / .uniqAdjacentBy<B>(B Function(T a) f) // chain (events)

강의

uniq는 "이 값을 언젠가 본 적이 있는가?"에 답합니다 — 지금까지 본 모든 값을 집합에 담아 둡니다. uniqAdjacent()는 다른 질문에 답합니다. "값이 바뀌었는가?" 각 원소를 바로 앞 원소와만 비교하므로 [1, 1, 2, 2, 1](1, 2, 1)이 됩니다 — 마지막 1은 살아남는데, 현재 구간의 반복이 아니라 새로운 구간이기 때문입니다.

그래서 반복 구간(run)을 접는 데 딱 맞는 연산자입니다. 매 틱마다 같은 상태를 다시 보고하는 상태 피드, 평평하게 유지되는 센서 값, 같은 레벨을 반복하는 로그 스트림 같은 것들입니다. seen 집합이 없으므로 시퀀스가 아무리 길어도 메모리는 일정하게 유지됩니다 — uniq라면 한없이 커졌을 끝없는 소스에서도 안전합니다. uniqAdjacentBy(key)는 유도한 키로 비교하며, uniqBy를 그대로 따릅니다.

Dart 고유의 추가 기능입니다(FxTS에는 대응물이 없습니다) — Rx는 distinctUntilChanged, Dart 스트림은 Stream.distinct라고 부릅니다. 비동기 키 콜백은 한 번에 한 원소씩 실행되지만(비교 자체가 본질적으로 순서에 묶여 있습니다), 상류는 여전히 concurrent 아래에서 병렬로 평가됩니다.

데모 1 · 반복 구간은 접고, 되돌아온 값은 남기기

데모 2 · 키 기준 상태 변화

직접 해 보기

연습: 센서의 구역(zone)이 바뀌는 순간만 보고해 보세요.

관련 항목: uniq — seen 집합을 쓰는 전역 중복 제거 · uniqBy — 키 기준 전역 중복 제거 · pairwise — 변화의 양쪽이 모두 필요할 때