I was wondering if there's an efficient/easy way to reorder a list of a list in by matching values of another list that sets the order. More specificly, if I'd have the following list:
[["a", "1", "2"], ["b", "2", "3"]]
I'd like to order it with the following list:
["b", "a"]
resulting in the newly ordered list:
[["b", "2", "3"], ["a", "1", "2"]]
Does anyone know how this can be done?
Thanks in advance!
Best Regards, Skyfe.
Basically this works by providing a special ordering function,
import Data.List
import Data.Ord
byLoc :: Eq a => [a] -> -- The list that we're sorting by
[a] -> -- First list
[a] -> -- Second list
Ordering
byLoc ords = comparing (elemIndex . head)
comparing
takes a function that takes in the two lists, and looks up the first element of each in our ordering list, comparing the location.
Then we just have
sortLoc ords = sortBy (byLoc ords)
and we're done. Unfortunately, this is really slow.
A faster solution is
import Data.Maybe
import Data.List
sortLoc ords xs = mapMaybe lookup ords
where lookup e = find ((==e) . head) xs
Here we're just looking up the appropriate element in our list in the mapMaybe
. If no element is found, then we just skip it.
Or if you want to support multiple elements with the same key
sortLoc ords xs = mapConcat lookup ords
where lookup e = filter ((==e) . head) xs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With