Haskell 哈斯克尔的elemIndices

Haskell 哈斯克尔的elemIndices,haskell,Haskell,我编写了获取元素索引的代码 elemIndex :: [String] -> [String] -> [Int] elemIndex [] [] = [] elemIndex x y = elemIndex True [(elem a y) | a <- x ] 返回空列表的步骤 你能解释一下下划线的用法吗 //编辑1 用于返回列表中值的索引 例如:elemIndex[“asde”、“zxc”、“qwe”][“qwe”、“zxc”] 返回[1,2]作为答案 谢谢 与 inde

我编写了获取元素索引的代码

elemIndex :: [String] -> [String] -> [Int]
elemIndex [] [] = []
elemIndex x y = elemIndex True [(elem a y) | a <- x ]
返回空列表的步骤

你能解释一下下划线的用法吗

//编辑1
用于返回列表中值的索引

例如:elemIndex[“asde”、“zxc”、“qwe”][“qwe”、“zxc”]

返回[1,2]作为答案

谢谢

index [] x = []
除非您不能使用等号右侧的

我不明白你想让elemIndex做什么

index [] x = []
除非您不能使用等号右侧的


我不明白你想让elemIndex做什么。

elemIndex
接受两个参数(两个列表)。现在,使用bool类型的附加参数递归调用它(即
True
)。那是行不通的。您可能想做的是创建一个helper函数,正如我一小时前所做的那样

作为形式参数使用的
\uu
匹配任何输入。它没有名称,因此,您不能使用匹配的名称

除此之外,您可能不想使用布尔数,而是整数(用于跟踪计数器)。
elem
函数只告诉您某个值是否是列表的一部分,而不是它所在的位置。所以,它对你没什么用处。由于这似乎是一个家庭作业,我不会为您的问题提供解决方案,但也许您应该将代码一分为二:

indices :: (Eq t) => [t] -> [t] -> [Integer]
getIndex :: (Eq t) => [t] -> t -> Integer
getIndex
可以使用辅助函数
getIndex'::(Eq t)=>[t]->t->Integer->Integer


编辑:一种可能的解决方案(使用hack,最好使用
Maybe
monad):

带有
Maybe
monad的版本:

indices :: (Eq t) => [t] -> [t] -> [Integer]
indices xs ys = filter (>= 0) $ map (getIndex xs) ys

getIndex :: (Eq t) => [t] -> t -> Integer
getIndex xs y = getIndex' xs y 0
  where
    getIndex' :: (Eq t) => [t] -> t -> Integer -> Integer
    getIndex' [] _ _                 = -1
    getIndex' (x:xs) y i | x == y    = i
                         | otherwise = getIndex' xs y (i + 1)
import Data.Maybe

indices :: (Eq t) => [t] -> [t] -> [Integer]
indices xs ys = mapMaybe (getIndex xs) ys

getIndex :: (Eq t) => [t] -> t -> Maybe Integer
getIndex xs y = getIndex' xs y 0
  where
    getIndex' :: (Eq t) => [t] -> t -> Integer -> Maybe Integer
    getIndex' [] _ _                 = Nothing
    getIndex' (x:xs) y i | x == y    = Just i
                         | otherwise = getIndex' xs y (i + 1)
以及将所有繁重工作留给标准库的版本:

import Data.List
import Data.Maybe

indices :: (Eq t) => [t] -> [t] -> [Int]
indices xs ys = mapMaybe (`elemIndex` xs) ys

elemIndex
接受两个参数(两个列表)。现在,使用bool类型的附加参数递归调用它(即
True
)。那是行不通的。您可能想做的是创建一个helper函数,正如我一小时前所做的那样

作为形式参数使用的
\uu
匹配任何输入。它没有名称,因此,您不能使用匹配的名称

除此之外,您可能不想使用布尔数,而是整数(用于跟踪计数器)。
elem
函数只告诉您某个值是否是列表的一部分,而不是它所在的位置。所以,它对你没什么用处。由于这似乎是一个家庭作业,我不会为您的问题提供解决方案,但也许您应该将代码一分为二:

indices :: (Eq t) => [t] -> [t] -> [Integer]
getIndex :: (Eq t) => [t] -> t -> Integer
getIndex
可以使用辅助函数
getIndex'::(Eq t)=>[t]->t->Integer->Integer


编辑:一种可能的解决方案(使用hack,最好使用
Maybe
monad):

带有
Maybe
monad的版本:

indices :: (Eq t) => [t] -> [t] -> [Integer]
indices xs ys = filter (>= 0) $ map (getIndex xs) ys

getIndex :: (Eq t) => [t] -> t -> Integer
getIndex xs y = getIndex' xs y 0
  where
    getIndex' :: (Eq t) => [t] -> t -> Integer -> Integer
    getIndex' [] _ _                 = -1
    getIndex' (x:xs) y i | x == y    = i
                         | otherwise = getIndex' xs y (i + 1)
import Data.Maybe

indices :: (Eq t) => [t] -> [t] -> [Integer]
indices xs ys = mapMaybe (getIndex xs) ys

getIndex :: (Eq t) => [t] -> t -> Maybe Integer
getIndex xs y = getIndex' xs y 0
  where
    getIndex' :: (Eq t) => [t] -> t -> Integer -> Maybe Integer
    getIndex' [] _ _                 = Nothing
    getIndex' (x:xs) y i | x == y    = Just i
                         | otherwise = getIndex' xs y (i + 1)
以及将所有繁重工作留给标准库的版本:

import Data.List
import Data.Maybe

indices :: (Eq t) => [t] -> [t] -> [Int]
indices xs ys = mapMaybe (`elemIndex` xs) ys

我将通过以下方式实现您的功能:

elemIndices acc n []  _ = acc
elemIndices acc n  _ [] = acc
elemIndices acc n (x:x') (y:y') = if x == y then 
                                      elemIndices (n:acc) (n+1) x' y'
                                  else
                                      elemIndices acc (n+1) x' (y:y')

elemIndex x y = reverse $ elemIndices [] 1 x y
当源代码列表中的元素与您查找的元素的顺序相同时,这将更加有效(不使用
elem
-tail递归)。例:


我将通过以下方式实现您的功能:

elemIndices acc n []  _ = acc
elemIndices acc n  _ [] = acc
elemIndices acc n (x:x') (y:y') = if x == y then 
                                      elemIndices (n:acc) (n+1) x' y'
                                  else
                                      elemIndices acc (n+1) x' (y:y')

elemIndex x y = reverse $ elemIndices [] 1 x y
当源代码列表中的元素与您查找的元素的顺序相同时,这将更加有效(不使用
elem
-tail递归)。例:


elemIndex没有通过打字检查。。。当elemIndex需要字符串列表时,您正在使用Bool。elemIndex应该做什么?它可以返回列表中值的索引。例如:elemIndex[“asde”,“zxc”,“qwe”][“qwe”,“zxc”]返回[1,2],因为答案是搜索的元素需要与源列表中的元素顺序相同?我只是想获得当前项目的索引。列表[“asde”、“zxc”、“qwe”]是固定的,如果元素在此列表中,我希望索引作为输出。elemIndex未通过类型检查器。。。当elemIndex需要字符串列表时,您正在使用Bool。elemIndex应该做什么?它可以返回列表中值的索引。例如:elemIndex[“asde”,“zxc”,“qwe”][“qwe”,“zxc”]返回[1,2],因为答案是搜索的元素需要与源列表中的元素顺序相同?我只是想获得当前项目的索引。列表[“asde”、“zxc”、“qwe”]是固定的,如果元素在此列表中,我希望索引作为输出。谢谢,我使用的代码提供了所需的输出。但我只是想找出解决这个问题的不同方法。很高兴听到你有一个解决办法。我更新了我的答案以包含我暗示的解决方案。我有点困惑ys=[“as”,“sas”]zip[1..]ys会给出[(1,“as”),(2,“sas”)]正如我前面提到的,elemIndex[“asde”,“zxc”,“qwe”[“qwe”,“zxc”]会产生[2,1],因为“qwe”的索引是2,“zxc”是1,所以在这种情况下zip函数有用吗?还是我用错了?thanksAh,在你的问题中,你说它应该是[1,2],而不是[2,1]。当我读到这篇文章时,我假设你想要第二个列表中的索引,1-索引。所以我最初的预感是正确的。我将在一分钟内添加另一个解决方案…完成(并根据我不正确的假设删除了代码;您仍然可以在编辑历史记录中找到它)。谢谢,我使用的代码为我提供了所需的输出。但我只是想找出解决这个问题的不同方法。很高兴听到你有一个解决办法。我更新了我的答案以包含我暗示的解决方案。我有点困惑ys=[“as”,“sas”]zip[1..]ys会给出[(1,“as”),(2,“sas”)]正如我前面提到的,elemIndex[“asde”,“zxc”,“qwe”[“qwe”,“zxc”]会产生[2,1],因为“qwe”的索引是2,“zxc”是1,所以在这种情况下zip函数有用吗?还是我用错了?thanksAh,在你的问题中,你说它应该是[1,2],而不是[2,1]。当我读到这篇文章时,我假设你想要第二个l中的索引