[英]Two way searching a list of tuples
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行。 任何帮助表示赞赏。
Haskell已经有了自己的lookup
功能 ,您应该可以使用它:
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]
扩展部分解决方案的一个好方法是将两个候选列表连接在一起,如:
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
这个; 但它经过列表只有一次。
您应该考虑查找可能会失败。 这里自然要做的就是返回一个结果列表:
lookup :: Eq a => a -> (a,a) -> [a]
lookup item xs = [ if a==c then b else a | (a,b) <- xs, a == c || b == c ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.