简体   繁体   English

获取Haskell中字符串列表中元素的位置

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM