我有以下Haskell代码,它从列表中返回所请求元素的实例(只是第一个实例),如果元素不存在则返回0。我试图返回列表中元素的位置,但不知道如何(我对编程很新)。
e.g。 'm''有些'正在返回m但我希望它返回3。
findMe x [] = 0
findMe x (y:ys) = if x == y
then x
else findMe x ys
答案 0 :(得分:3)
试试这个。如果由于元素不存在而返回0
,我认为它是1
索引开始。
findMe x list = findMeP list 1
where
findMeP [] _ = 0
findMeP (y:ys) n
| x == y = n
| otherwise = findMeP ys (n + 1)
作为演示,请查看this。
答案 1 :(得分:3)
虽然之前的答案是正确的,但这是一个我更喜欢的解决方案,因为它使用了基本库中的基本构建块,并避免了显式的递归。
import Data.List (find) {- for find :: (a -> Bool) -> [a] -> Maybe a -}
findMe :: Eq a => a -> [a] -> Maybe (Int, a)
findMe x = find ((== x).snd) . zip [1..]
该函数返回元素及其索引,从零开始计算,包含在Maybe
类型中。如果未找到该元素,则返回Nothing
。
要单独提取元素或索引,可以在fst
结果上映射snd
和Maybe
函数:
findMeIndex = fmap fst . findMe
findMeElem = fmap snd . findMe
示例:
findMe 'c' ['a','b','c','d'] == Just (2,'c')
findMe 'z' ['a','b','c','d'] == Nothing
findMeIndex 'c' ['a','b','c','d'] == Just 2
findMeIndex 'z' ['a','b','c','d'] == Nothing
如果您需要从1
开始计算,则可以将[0..]
替换为[1..]
。在任何一种情况下,将结果包装在Maybe
中最好返回一些特殊值来表示缺少元素(比如-1
或0
),因为那样用户就不会误会解释你的结果。例如,如果您从1
计算并在失败时返回0
,并且有人使用您的函数错误地认为您从0
开始计算,则他们可能会将失败解释为已找到该元素在第一个位置。相反,用户被迫明确处理故障情况。
该功能的工作原理如下。 zip [0..]
生成一个将每个元素与其索引耦合的对的列表,从零开始([0..]
是无限列表[0,1,2,3,..]
)。然后,find
扫描列表(与OP的原始代码完全相同),返回函数((== x).snd)
返回True
的第一个元素,包含在Maybe
中如果找到,则输入,否则输入Nothing
。 find
寻找哪个元素?请记住,find
附带对列表。因此,通过将snd
函数与(== x)
组合,我们找到第二个组件等于x