获取haskell列表中的multiples元素的索引

时间:2016-03-05 18:13:51

标签: list haskell indexing

我有一个像[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]

2 个答案:

答案 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..]

因此,假设NB居住的类型是Eq的实例,您可以这样做:

indexesOf N [B,B,N,B,N]

得到答案:

[2,4]

但是,这只是来自elemIndices

Data.List