1 of 7

Iterator Unique

for Stage 1

Michael Ficarra • January 2024

2 of 7

problem: only get distinct values from an iterator

Iterator.from("Mississippi").distinct();

// ⇒ "M", "i", "s", "p"

let states = ["Alabama", "Alaska", "Arizona", ...];

Iterator.from(states).distinctBy(state => state[0]);

// ⇒ "Alabama", "California", "Delaware", "Florida", ...

3 of 7

design considerations

  • still no good solution for composite keys
    • but that's an unsolved problem generally
    • mapper leaves the door open for later support
  • mapper? comparator? both? neither?
    • mapper allows for much more efficient implementation than comparator
    • separate methods or combined with optional params?
    • would mapper be passed an index?
  • naming: distinct / unique / uniq are all common

4 of 7

prior art: other languages

language

library

simple API

with comparator

with mapping

Clojure

core

distinct

--

--

Elm

List.Extra

unique

--

uniqueBy

Haskell

Data.List

nub

nubBy

--

Java

Stream

distinct

--

--

Kotlin

Sequence

distinct

--

distinctBy

.NET

System.Linq

Distinct

Distinct, DistinctBy

DistinctBy

PHP

array

array_unique

--

--

Python

more-itertools

unique_everseen

--

unique_everseen

Ruby

Enumerable

uniq

--

uniq

Scala

Seq

distinct

--

distinctBy

Shell

GNU coreutils

uniq

--

--

notably absent: Rust Iterators, Swift Sequences

5 of 7

prior art: JS libraries

library

simple API

with comparator

with mapping

extra-iterable

unique

unique

unique

iter-ops

distinct

--

distinct

iter-tools

distinct

--

distinct

itertools-ts

distinct

--

distinct

Lodash / Underscore

uniq

uniqWith

uniqBy

Ramda

uniq

uniqWith

uniqBy

sequency

distinct

--

distinctBy

wu

unique

--

--

6 of 7

champion's preferences

  • comparator style API would not be efficient
  • single method with optional mapper
    • mapper not provided an index
  • no preference on name among
    • distinct / distinctBy
    • unique / uniqueBy
    • uniq / uniqBy

7 of 7

Stage 1?