Skip to content

Commit b9098ca

Browse files
committed
Make list.unique loglinear instead of quadratic
1 parent 32f29ae commit b9098ca

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
- Fixed a bug where `list.unique` had quadratic complexity instead of loglinear.
56
- The `bit_array` module gains the `bit_size` and `starts_with` functions.
67
- Ths `string` module gains the `drop_start`, `drop_end`, `pad_start`,
78
`pad_end`, `trim_start`, and `trim_end` functions. These replace the

src/gleam/list.gleam

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,10 +1166,18 @@ fn intersperse_loop(list: List(a), separator: a, acc: List(a)) -> List(a) {
11661166
/// ```
11671167
///
11681168
pub fn unique(list: List(a)) -> List(a) {
1169-
case list {
1170-
[] -> []
1171-
[x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))]
1172-
}
1169+
let #(result_rev, _) =
1170+
// We can't use `gleam/set` here, as it would create an import cycle
1171+
// (`gleam/set` depends on `gleam/list`), so we're using `gleam/dict` instead.
1172+
list
1173+
|> fold(#([], dict.new()), fn(acc, x) {
1174+
let #(result_rev, seen) = acc
1175+
case dict.has_key(seen, x) {
1176+
False -> #([x, ..result_rev], dict.insert(seen, x, Nil))
1177+
True -> #(result_rev, seen)
1178+
}
1179+
})
1180+
result_rev |> reverse
11731181
}
11741182

11751183
/// Sorts from smallest to largest based upon the ordering specified by a given

0 commit comments

Comments
 (0)