Chadtech / unique-list / List.Unique

An ordered list that contains unique elements.


type UniqueList a

A list that has no duplicate elements, much like a Set. However, UniqueList preserves the initial order of elements and does not require that elements be comparable.

Create

fromList : List a -> UniqueList a

Create a UniqueList from a List.

Note: Elements are placed in the position at which they occurred last.

fromList [ 3, 1, 2, 3 ]
--> fromList [ 1, 2, 3 ]

empty : UniqueList a

Create an empty UniqueList.

empty
--> fromList []

Transform

cons : a -> UniqueList a -> UniqueList a

Add an element to the front of a UniqueList.

Note: If the element was already in the list, it will be moved to the front of the list.

-- Add an element
cons 1 (fromList [ 2, 3, 4 ])
--> fromList [ 1, 2, 3, 4 ]

-- Move an element
cons 3 (fromList [ 1, 2, 3 ])
--> fromList [ 3, 1, 2 ]

remove : a -> UniqueList a -> UniqueList a

Remove a value from a UniqueList if the value is present.

remove 2 (fromList [ 1, 2, 3 ])
--> fromList [ 1, 3 ]

remove 0 (fromList [ 1, 2, 3 ])
--> fromList [ 1, 2, 3 ]

reverse : UniqueList a -> UniqueList a

Reverse a UniqueList.

reverse (fromList [ "second", "first" ])
--> fromList [ "first", "second" ]

reverse (fromList [ 3, 2, 1 ])
--> fromList [ 1, 2, 3, 3 ]

addBefore : a -> a -> UniqueList a -> UniqueList a

Add an element to a UniqueList before another element.

Note: If the added element is already in the list, it will be moved to the new position.

-- Add an element
addBefore 2 6 (fromList [ 0, 2, 1 ])
--> fromList [ 0, 6, 2, 1 ]

-- Move an element
addBefore 4 1 (fromList [ 1, 2, 3, 4 ])
--> fromList [ 2, 3, 1, 4 ]

-- No effect
addBefore 0 1 (fromList [ 1, 2 ])
--> fromList [ 1, 2 ]

addAfter : a -> a -> UniqueList a -> UniqueList a

Add an element to a UniqueList after another element

Note: If the added element is already in the list, it will be moved to the new position.

-- Add an element
addAfter 2 3 (fromList [ 1, 2, 4, 5 ])
--> fromList [ 1, 2, 3, 4, 5 ]

-- Move an element
addAfter 4 1 (fromList [ 1, 2, 3, 4 ])
--> fromList [ 2, 3, 4, 1 ]

-- No effect
addAfter 0 1 (fromList [ 1, 2 ])
--> fromList [ 1, 2 ]

toList : UniqueList a -> List a

Turn a UniqueList into a List.

toList (fromList [ 1, 1 ])
--> [1]

Query

length : UniqueList a -> Basics.Int

Determine the number of elements in a UniqueList.

-- Without duplicates
length (fromList [ 1, 2, 3 ])
--> 3

-- With duplicates
length (fromList [ 2, 2, 2 ])
--> 1

member : a -> UniqueList a -> Basics.Bool

Determine if a UniqueList contains a value.

member 4 (fromList [ 1, 4, 6 ])
--> True

member "cat" (fromList [ "dog", "bird" ])
--> False

isEmpty : UniqueList a -> Basics.Bool

Check if a UniqueList is empty.

isEmpty (fromList [])
--> True

isEmpty (fromList [ 1 ])
-->  False

isFirst : a -> UniqueList a -> Maybe Basics.Bool

Check if an element is the first in a UniqueList.

Returns Nothing if the list is empty.

isFirst 1 (fromList [1,2,3])
--> Just True

isFirst 1 empty
--> Nothing

isBefore : a -> a -> UniqueList a -> Maybe Basics.Bool

Check if an element is before another in a UniqueList.

Returns Nothing if either of the elements being queried are not in the list.

('A' |> isBefore 'C') (fromList [ 'A', 'B', 'C' ])
--> Just True

('D' |> isBefore 'B') (fromList [ 'B', 'C', 'D' ])
--> Just False

('Z' |> isBefore 'B') (fromList [ 'A', 'B' ])
--> Nothing

isAfter : a -> a -> UniqueList a -> Maybe Basics.Bool

Check if an element is after another in a UniqueList.

Returns Nothing if either of the elements being queried are not in the list.

('D' |> isAfter 'B') (fromList [ 'B', 'C', 'D' ])
--> Just True

('A' |> isAfter 'C') (fromList [ 'A', 'B', 'C' ])
--> Just False


('Z' |> isAfter 'B') (fromList [ 'A', 'B' ])
--> Nothing

Helpers

filterDuplicates : List a -> List a

Remove duplicates from a list without using the UniqueList type.

Note: Elements are placed in the position at which they occurred last.

Similar to the unique function in elm-community/list-extra, however List.Extra.unique only works on List comparable.

filterDuplicates [ True, True ]
--> [ True ]

filterDuplicates [ 1, 1, 2, 3, 5 ]
--> [ 1, 2, 3, 5 ]

filterDuplicates [ 1, 2, 3, 4, 1 ]
--> [ 2, 3, 4, 1 ]