我有一个像[B,B,N,B,N]
的列表,我想要检索N
的所有索引。因此,在此示例中,它将是[2,4]
。
我真的不知道该怎么做...我试过elemIndex
但事实上我并不认为在我的情况下它是允许的,因为&# 39;这是练习的重点。
我现在这样做但我知道它不起作用:
indice :: [Case] -> [Int]
indice [] = [0]
indice (x:xs)
| x == N = [1 + head(indice(xs))] ++ indice(xs)
| x == B = [1]
答案 0 :(得分:3)
您的源代码存在一些问题:最重要的是B
的情况和空列表生成包含项目的列表:
indice :: [Case] -> [Int]
indice [] = [0] -- <- list with elements?
indice (x:xs)
| x == N = [1 + head(indice(xs))] ++ indice(xs)
| x == B = [1] -- <- list with elements?
尽管如此,我认为在这种情况下你最好使用 accumulator :在递归调用期间更新的变量。在这种情况下,累加器是i
:我们的“光标”所在的索引。我们可以使用累加器,使indice
调用辅助函数:
indice :: [Case] -> [Int]
indice = helper 0
where helper --...
现在我们仍然需要定义我们的helper
函数。
此外,有三种情况我们需要照顾:
我们到达了列表的末尾,在这种情况下我们也返回一个空列表:
helper _ [] = []
光标位于N
,我们“发出”索引并进行递归调用以更新索引:
helper i (N:xs) = i : helper (i+1) xs
光标位于另一个字符处,我们只需向前移动光标并更新索引:
helper i (_:xs) = helper (i+1) xs
总而言之,我们获得:
indice :: [Case] -> [Int]
indice = helper 0
where helper _ [] = []
helper i (N:xs) = i : helper (i+1) xs
helper i (_:xs) = helper (i+1) xs
答案 1 :(得分:3)
您可以使用zip
使用索引标记每个元素,过滤符合条件的元素,然后删除值,只留下索引:
indexesOf :: Eq a => a -> [a] -> [Int]
indexesOf v = map fst . filter ((== v) . snd) . zip [0..]
因此,假设N
和B
居住的类型是Eq
的实例,您可以这样做:
indexesOf N [B,B,N,B,N]
得到答案:
[2,4]
但是,这只是来自elemIndices
Data.List