我的头衔可能有些偏差,我会尝试更好地解释一下我想要实现的目标。
基本上我要说我有一个清单:
["1234x4","253x4",2839",2845"]
现在我想将包含元素5的字符串的所有位置添加到新列表中。在当前示例中,结果列表将是:
[1,3]
为此我已经为elem
完成了类似的功能:
myElem [] _ = False
myElem [x] number =
if (firstCheck x) then if digitToInt(x) == number then True else False else False
myElem (x:xs) number =
if (firstCheck x) then (if digitToInt(x) == number then True else myElem xs number) else myElem xs number
其中firstCheck x
检查checked元素不是'x'或'#'
现在在我当前的函数中,我获得了包含元素的第一个元素位置,但是我的头部仍然在如何获取完整列表:
findBlock (x:xs) number arv =
if myElem x number then arv else findBlock xs number arv+1
arv
为0且number
是我正在寻找的数字。
例如输入:
findBlock ["1234x4","253x4",2839",2845"] 5 0
结果将是1
任何帮助都将不胜感激。
答案 0 :(得分:7)
您想要的功能已存在于Data.List
模块中,名称为findIndices
。您只需使用(elem '5')
作为谓词。
http://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#v:findIndices
如果由于某种原因,你不允许使用内置的,它会有一个非常漂亮的定义(虽然实际使用的那个有一个更复杂,更有效的一个):
findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
顺便说一句,我通过在Hoogle中搜索[a] -> (a -> Bool) -> [Int]
类型找到了这个函数,其中(模数参数排序)显然是函数必须具有的类型。找出Haskell的最佳方法是考虑它需要的类型并搜索Hoogle或Hayoo的类型。 Hoogle是更好的IMO,因为它在类型上略有模糊匹配;例如Hayoo不会通过我给出的类型在这里找到函数,因为它以相反的顺序接受参数。
答案 1 :(得分:3)
findIndices
的实现,用于教学目的:
findIndices ok list = f list 0 where
f [] _ = []
f (x:xs) ix
| ok x = ix : f xs (ix+1)
| otherwise = f xs (ix+1)
像findIndices (elem '5') my_list_o_strings
答案 2 :(得分:1)
您正试图通过列表工作,跟踪您在列表中的位置。这样做最简单的功能是
mapWithIndex :: (Int -> a -> b) -> [a] -> [b]
mapWithIndex = mwi 0 where
mwi i _f [] = i `seq` []
mwi i f (x:xs) = i `seq` f i x : mwi (i+1) f xs
这需要一个函数和一个列表,并将该函数应用于每个索引和元素。所以
mapWithIndex (\i x -> (i, x)) ['a', 'b', 'c'] =
[(0,'a'), (1,'b'),(2,'c')]
完成后,您可以filter
列表获得您想要的对:
filter (elem '5' . snd)
然后map fst
覆盖它以获取索引列表。
更综合的方法是使用foldrWithIndex
。
foldrWithIndex :: (Int -> a -> b -> b) -> b -> [a] -> b
foldrWithIndex = fis 0 where
fis i _c n [] = i `seq` n
fis i c n (x:xs) = i `seq` c i x (fis (i+1) c n xs)
这使您可以一步完成所有事情。
事实证明,您可以非常巧妙地使用foldrWithIndex
实施foldr
,这使得它可用于任何Foldable
容器:
foldrWithIndex :: (Foldable f, Integral i) =>
(i -> a -> b -> b) -> b -> f a -> b
foldrWithIndex c n xs = foldr go (`seq` n) xs 0 where
go x r i = i `seq` c i x (r (i + 1))
反正
findIndices p = foldrWithIndex go [] where
go i x r | p x = i : r
| otherwise = r