From bd0da5a16170e0377aa547344f419425cd036474 Mon Sep 17 00:00:00 2001 From: Radek Micek Date: Wed, 14 Aug 2024 11:30:10 +0200 Subject: [PATCH] Make `list.unique` logarithmic instead of quadratic --- src/gleam/list.gleam | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index 530a27f8..f1701185 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -1151,7 +1151,7 @@ pub fn intersperse(list: List(a), with elem: a) -> List(a) { /// Removes any duplicate elements from a given list. /// -/// This function returns in loglinear time. +/// This function returns in logarithmic time. /// /// ## Examples /// @@ -1161,10 +1161,16 @@ pub fn intersperse(list: List(a), with elem: a) -> List(a) { /// ``` /// pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } + let #(result_rev, _) = + list + |> fold(#([], dict.new()), fn(acc, x) { + let #(result_rev, seen) = acc + case dict.has_key(seen, x) { + False -> #([x, ..result_rev], dict.insert(seen, x, Nil)) + True -> #(result_rev, seen) + } + }) + result_rev |> reverse } /// Sorts from smallest to largest based upon the ordering specified by a given