Skip to content

Instantly share code, notes, and snippets.

@PedroHLC
Created January 20, 2022 13:23
Show Gist options
  • Save PedroHLC/23ba27974deb18a8ab15922dd6dacb0e to your computer and use it in GitHub Desktop.
Save PedroHLC/23ba27974deb18a8ab15922dd6dacb0e to your computer and use it in GitHub Desktop.
module AlphanumericSorter exposing (AlphanumericSortConfig, alphanumericSort)
type alias AlphanumericSortConfig item =
{ retrieve : item -> String
, smallerFirst : Bool
, emptyOnTail : Bool
, numbersFirst : Bool
}
alphanumericSort : AlphanumericSortConfig item -> List item -> List item
alphanumericSort { retrieve, smallerFirst, emptyOnTail, numbersFirst } list =
let
nonEmptySort nonEmptyList =
if smallerFirst then
List.sortWith
(\a b -> compareSmallerFirst (retrieve a) (retrieve b))
nonEmptyList
else
List.sortBy retrieve nonEmptyList
alphanumericMerge ( numbers, alphanums, empties ) =
let
sortedNumbers =
numbers
|> List.sortBy Tuple.first
|> List.map Tuple.second
sortedAlphanums =
nonEmptySort alphanums
in
if emptyOnTail then
sortedNumbers ++ sortedAlphanums ++ empties
else
empties ++ sortedNumbers ++ sortedAlphanums
in
if numbersFirst then
List.foldr
(alphanumericPartition retrieve)
( [], [], [] )
list
|> alphanumericMerge
else if emptyOnTail then
List.partition (retrieve >> String.isEmpty)
list
|> Tuple.mapSecond nonEmptySort
|> (\( a, b ) -> b ++ a)
else
nonEmptySort list
compareSmallerFirst : String -> String -> Order
compareSmallerFirst a b =
case compare (String.length a) (String.length b) of
EQ ->
compare a b
another ->
another
alphanumericPartition :
(item -> String)
-> item
-> ( List ( Float, item ), List item, List item )
-> ( List ( Float, item ), List item, List item )
alphanumericPartition retrieve elem ( numbers, alphanums, empties ) =
let
string =
retrieve elem
in
if String.isEmpty string then
( numbers, alphanums, elem :: empties )
else
case String.toFloat string of
Just float ->
( ( float, elem ) :: numbers, alphanums, empties )
Nothing ->
( numbers, elem :: alphanums, empties )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment