2009-05-16 6 views
0

moi avons écrit le code pour obtenir l'index de l'élémentelemIndices à Haskell

elemIndex :: [String] -> [String] -> [Int] 
elemIndex [] [] = [] 
elemIndex x y = elemIndex True [(elem a y) | a <- x ] 

est-il un moyen/similer alternative de réaliser la logique ci-dessus?

et aussi j'ai vu que certains utilisent

index [] _ = [] 

pour retourner les listes null

pourriez-vous svp expliquer l'utilisation de underscore?

// éditer 1 il est prévu de renvoyer l'index des valeurs dans la liste.

par exemple: elemIndex [ "ASDE", "zxc", "qwe"] [ "qwe", "zxc"]

retours [1,2] comme la réponse

grâce

+1

elemIndex ne passe pas le typechecker ... vous utilisez un Bool quand elemIndex attend une liste de chaînes. Qu'est-ce que elemIndex est censé faire? – Jonas

+0

il est prévu de renvoyer l'index des valeurs dans la liste. par exemple: elemIndex [ "ASDE", "zxc", "qwe"] [ "qwe", "zxc"] retours [1,2] comme la réponse – pier

+0

sont les éléments recherchés nécessaires pour être dans le même commander comme dans la liste des sources? – Dario

Répondre

3

elemIndex prend deux arguments (deux listes). En ce moment, vous l'appelez récursivement avec un argument supplémentaire de type bool (à savoir True). Ça ne marchera pas. Ce que vous voulez probablement faire, c'est créer une fonction d'aide, comme je l'ai showed you il y a une heure.

Le _, utilisé comme argument formel, correspond à n'importe quelle entrée. Il n'a pas de nom, et en tant que tel, vous ne pouvez pas utiliser celui qui correspond. En dehors de cela, vous ne voulez probablement pas utiliser de booléens, mais des entiers (pour garder la trace d'un compteur). La fonction elem vous indique seulement si une certaine valeur fait partie d'une liste, pas il est. Donc, cela vous est peu utile. Comme il semble devoir, je ne vais pas donner une solution à votre problème, mais peut-être que vous devez diviser votre code en deux:

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

(getIndex peut utiliser une fonction d'assistance getIndex' :: (Eq t) => [t] -> t -> Integer -> Integer.)


Modifier: Une solution possible (qui utilise une astuce, il est plus agréable d'utiliser le Maybe monade):

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) 

Une version avec le Maybe monade:

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) 

Et une version qui laisse toutes les charges lourdes à la bibliothèque standard:

import Data.List 
import Data.Maybe 

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

merci, le code que j'ai utilisé me donne la sortie désirée. mais je veux trouver un différent de s'attaquer à la question. – pier

+0

Bon d'entendre que vous avez une solution. J'ai mis à jour ma réponse pour inclure la solution que j'ai suggérée. – Stephan202

+0

im confondre un peu ys = [ "tel", "sas"] zip [1 ..] ys woudl donnent [(1, "comme"), (2, "sas")] comme ive mentionné précédemment, elemIndex ["asde", "zxc", "qwe"] ["qwe", "zxc"] donnerait [2,1] puisque l'indice de "qwe" est 2 et "zxc" est 1 donc dans ce cas, la fonction de fermeture éclair est utile? ou l'ai-je incorrectement utilisé? merci – pier

2
index [] _ = [] 

est le même que

index [] x = [] 

sauf que vous ne pouvez pas utiliser le _ sur le côté droit du signe égal. Je ne comprends pas ce que vous voulez faire elemIndex.

0

Je mettre en œuvre votre fonction de cette façon:

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 

Lorsque les éléments de votre liste de sources sont dans le même ordre que les éléments que vous recherchez, ce qui est beaucoup plus efficace (aucune utilisation de elem - récursion de la queue). Ex:

elemIndex [3..7] [4, 6] -- Yields [2, 4] 
+0

Ah - Je me suis trompé. Vous voulez avoir les indices dans la première liste. Pardon – Dario