Searching through list of tuples

谁说胖子不能爱 提交于 2021-02-05 10:43:05

问题


I'm trying to write a function that accepts a string and a list of tuple pairs. I want to search through the list of tuples, and if the first value in the tuple matches the input string, I want to return the second value in the pair. I believe it functions similar to the lookup function, but I'm not sure how to implement it. Here is my thinking so far:

search :: a -> [(a,b)] -> Maybe b
search a (x:xs) = if a == first value in x, return second value in x
-- If a is not in the list of tuples, return "Nothing"

An example of this would be:

search "x" ([("x", 3), ("z", 5)]) = 3
search "x" ([("y", 3), ("z", 5)]) = Nothing

回答1:


find can retrieve the first element satisfying an arbitrary condition, and so you might build your function around it:

-- 'fmap snd' acts on the 'Maybe (a, b)' that 'find' gives back.
search :: Eq a => a -> [(a,b)] -> Maybe b
search a = fmap snd . find ((== a) . fst)

Note that this is exactly the same as lookup. Also, as leftaroundabout points out, 3 (as opposed to Just 3) is not a possible result for a function with a Maybe b result type. You can eliminate the Maybe wrapping when you actually need to use the result using, for instance, the maybe function:

GHCi> :t maybe
maybe :: b -> (a -> b) -> Maybe a -> b
GHCi> (maybe "No x" (("x ~> " ++) . show) . search "x") ([("x", 3), ("z", 5)])
"x ~> 3"
GHCi> (maybe "No x" (("x ~> " ++) . show) . search "x") ([("y", 3), ("z", 5)])
"No x"



回答2:


In the base case, if list is empty, it returns Nothing. Then, if first element a of tuple in the head is equal to element x, it returns second element Just b. Else, recursively, it searchs in the tail.

search :: (Eq a) => a -> [(a,b)] -> Maybe b
search _ [] = Nothing
search x ((a,b):xs) = if x == a then Just b else search x xs

You can implement an unsafe version without Maybe:

search :: (Eq a) => a -> [(a,b)] -> b
search _ [] = error "element not found"
search x ((a,b):xs) = if x == a then b else search x xs

Other option is searching a list instead of first ocurrence, then, empty list [] is equivalent to Nothing:

search :: (Eq a) => a -> [(a,b)] -> [b]
search x = map snd . filter ((==x).fst)



回答3:


Just use a simple map combined with a lambda:

searchMe :: (Eq a) => a -> [(a, b)] -> [Maybe b]
searchMe a li = map (\(x, y) -> if a == x then Just y else Nothing ) li

OP your function, as it is, won't work as you are defining your list parameter as (x : xs), which won't enable you to apply operations to elements of the tuple.



来源:https://stackoverflow.com/questions/40566940/searching-through-list-of-tuples

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!