2013-09-30 92 views
4

我想知道是否有一種有效/簡單的方法,通過匹配設置順序的另一個列表的值來重新排列列表的列表。更specificly,如果我有以下列表:Haskell通過匹配值重排列表

[["a", "1", "2"], ["b", "2", "3"]] 

我想用下面的列表來訂購吧:

["b", "a"] 

導致新有序列表:

[["b", "2", "3"], ["a", "1", "2"]] 

有誰知道這可以做到嗎?

在此先感謝!

最好的問候, Skyfe。

+0

什麼是第二個名單是如何設置的第一順序的規則多個元素?看起來您打算讓第二個列表中的元素分別代表第一個列表中的其中一個子列表的第一個元素,但我不確定。請澄清。 – jacobm

+0

是的,第二個列表中的元素指定第一個列表中的第一個子列表。解決方案jozefg提供符合此要求 – Skyfe

回答

6

基本上這部作品提供了一個特殊的排序功能,

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需要一個函數,它在兩個列表,並查找每一個在我們的排序列表的第一個元素,比較的位置。

那麼我們就必須

sortLoc ords = sortBy (byLoc ords) 

,我們就大功告成了。不幸的是,這真的很慢。

一個更快的解決方案是

import Data.Maybe 
import Data.List 
sortLoc ords xs = mapMaybe lookup ords 
    where lookup e = find ((==e) . head) xs 

在這裏,我們只是希望在了我們的mapMaybe列表中的相應元素。如果找不到元素,那麼我們就跳過它。

或者,如果你想支持使用相同的密鑰

sortLoc ords xs = mapConcat lookup ords 
    where lookup e = filter ((==e) . head) xs 
+0

完美!像魅力一樣工作,非常感謝你! – Skyfe

+0

@Skyfe樂於助人 – jozefg