[英]Get positions of elements in list of strings in Haskell
my title might be a bit off and i'll try to explain a bit better what i'm trying to achieve. 我的头衔可能有点偏,我会试着更好地解释一下我想要实现的目标。
Basically let's say i have a list: 基本上我要说我有一个清单:
["1234x4","253x4",2839",2845"]
Now i'd like to add all the positions of the strings which contain element 5 to a new list. 现在我想将包含元素5的字符串的所有位置添加到新列表中。 On a current example the result list would be:
在当前示例中,结果列表将是:
[1,3]
For that i've done similar function for elem
: 为此我已经为
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
where firstCheck x
checks that the checked element isn't 'x' or '#' 其中
firstCheck x
检查checked元素不是'x'或'#'
Now in my current function i get the first element position which contains the element, however my head is stuck around on how to get the full list: 现在,在我当前的函数中,我获得了包含元素的第一个元素位置,但是我的头部仍然在如何获取完整列表:
findBlock (x:xs) number arv =
if myElem x number then arv else findBlock xs number arv+1
Where arv
is 0 and number
is the number i'm looking for. 其中
arv
为0, number
是我正在寻找的数字。
For example on input: 例如输入:
findBlock ["1234x4","253x4",2839",2845"] 5 0
The result would be 1 结果将是1
Any help would be appreciated. 任何帮助,将不胜感激。
The function you want already exists in the Data.List
module, by the name of findIndices
. 您想要的函数已经存在于
Data.List
模块中,名称为findIndices
。 You can simply use (elem '5')
as the predicate. 您可以简单地使用
(elem '5')
作为谓词。
http://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#v:findIndices http://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#v:findIndices
If, for some reason, you're not allowed to use the built-in one, it comes with a very pretty definition (although the one actually used has a more complicated, more efficient one): 如果,由于某种原因,你不允许使用内置的,它带有一个非常漂亮的定义(虽然实际使用的那个有一个更复杂,更有效的一个):
findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
By the way, I found this function by searching Hoogle for the type [a] -> (a -> Bool) -> [Int]
, which (modulo parameter ordering) is obviously the type such a function must have. 顺便说一句,我通过搜索Hoogle的类型
[a] -> (a -> Bool) -> [Int]
找到了这个函数,其中(模数参数排序)显然是函数必须具有的类型。 The best way to find out of Haskell has something is to think about the type it would need to have and search Hoogle or Hayoo for the type. 找出Haskell的最佳方法是考虑它需要的类型并搜索Hoogle或Hayoo的类型。 Hoogle is better IMO because it does slightly fuzzy matching on the type;
Hoogle是更好的IMO,因为它在类型上略有模糊匹配; eg Hayoo wouldn't find the function here by the type I've given, because it take the arguments in the reverse order.
例如,Hayoo不会通过我给出的类型在这里找到函数,因为它以相反的顺序获取参数。
An implementation of findIndices
, for instructional purposes: 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)
Use it like findIndices (elem '5') my_list_o_strings
像
findIndices (elem '5') my_list_o_strings
一样使用它
You're trying to work your way through a list, keeping track of where you are in the list. 您正试图通过列表工作,跟踪您在列表中的位置。 The simplest function for doing this is
这样做最简单的功能是
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
This takes a function and a list, and applies the function to each index and element. 这需要一个函数和一个列表,并将该函数应用于每个索引和元素。 So
所以
mapWithIndex (\i x -> (i, x)) ['a', 'b', 'c'] =
[(0,'a'), (1,'b'),(2,'c')]
Once you've done that, you can filter
the list to get just the pairs you want: 完成后,您可以
filter
列表以获得所需的对:
filter (elem '5' . snd)
and then map fst
over it to get the list of indices. 然后
map fst
到它上面以获得索引列表。
A more integrated approach is to use foldrWithIndex
. 更集成的方法是使用
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)
This lets you do everything in one step. 这使您可以一步完成所有操作。
It turns out that you can implement foldrWithIndex
using foldr
pretty neatly, which makes it available for any Foldable
container: 事实证明,您可以使用
foldr
非常巧妙地实现foldrWithIndex
,这使得它可用于任何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))
Anyway, 无论如何,
findIndices p = foldrWithIndex go [] where
go i x r | p x = i : r
| otherwise = r
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.