From 8a68cacf005cb9985dd44c1a269facf88b059923 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Sat, 25 Jan 2025 16:18:15 +0100 Subject: [PATCH] Fix implementation of list.unique --- CHANGELOG.md | 4 ++++ src/gleam/list.gleam | 13 +++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 343c78a2..6fb78ec5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- Fixed a bug that would result in `list.unique` having quadratic runtime. + ## v0.53.0 - 2025-01-23 - `io.print` will now work in JavaScript environments where the `process` diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index b3ab350d..fb66b890 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -1159,9 +1159,18 @@ fn intersperse_loop(list: List(a), separator: a, acc: List(a)) -> List(a) { /// ``` /// pub fn unique(list: List(a)) -> List(a) { + unique_loop(list, dict.new(), []) +} + +fn unique_loop(list: List(a), seen: Dict(a, Nil), acc: List(a)) -> List(a) { case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] + [] -> reverse(acc) + [first, ..rest] -> + case dict.has_key(seen, first) { + True -> unique_loop(rest, seen, acc) + False -> + unique_loop(rest, dict.insert(seen, first, Nil), [first, ..acc]) + } } }