双向搜索元组列表

时间:2013-11-26 01:42:08

标签: haskell

tuplesList = [('a','m'), ('b', 'n'), ('c', 'o'), etc]

如何通过首先查看第一个元素并返回第二个元素来搜索此列表中的值,但如果找不到,则查看第二个元素并返回第一个元素(如果找到)。例如搜索'a'会返回'm'并搜索'n'会返回'b'吗?

我试过了:

lookup :: Char -> [(Char,Char)] -> Char

lookup x zs = (head [b | (a,b) <- zs, (a==x)])

lookup x zs = (head [a | (a,b) <- zs, (b==x)])

但是我不知道怎么说如果第二行没有找到匹配,那么第3行。 任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:1)

Haskell已经有its own lookup function你应该可以使用:

lookup' :: Char -> [(Char,Char)] -> Char
lookup' x zs = case (search1, search2) of
                    (Just y,  _)       -> y
                    (Nothing, Just y)  -> y
                    (Nothing, Nothing) -> error "What am I supposed to do here I DON'T KNOW"
 where search1 = lookup x zs
       search2 = lookup x [(b,a) | (a,b) <- zs]

答案 1 :(得分:1)

扩展部分解决方案的一个好方法是将两个候选列表连接在一起,如:

lookup x zs = head ([ b | (a,b) <- zs, a == x ] ++ [ a | (a,b) <- zs, b == x ])

你知道为什么会这样吗?


它不是最高效的,因为如果元组的第一个组件没有匹配,它将经过zs两次 - 如果zs非常大,则保持zs超过必要的时间。

为了改善我会做这样的事情(但只有当它非常重要时!):

lookup x zs = goNoSecondBestYet zs where
    goNoSecondBestYet [] = error "Nothing found"
    goNoSecondBestYet ((a,b):abs) 
        | a == x = b -- we're done!
        | b == x = goSecondBestFound b abs -- keep track of the newly found second best candidate
        | otherwise = goNoSecondBestYet abs -- just go on
    goSecondBestFound y [] = y
    goSecondBestFound y ((a,b):abs)
        | a == x = b -- we're done, never mind the second best
        | otherwise = goSecondBestFound y abs -- keep going, we already have a second best

这已经非常复杂了(尝试将其概括为使用4元组来查看我的意思!)我通常会使用Maybe来实现此目的;但它 只通过列表一次。

答案 2 :(得分:0)

您应该考虑查找可能会失败。这里自然要做的就是返回一个结果列表:

lookup :: Eq a => a -> (a,a) -> [a]
lookup item xs = [ if a==c then b else a | (a,b) <- xs, a == c || b == c ]