2013-09-30 100 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