Mein Titel könnte ein bisschen abweichen und ich werde versuchen, ein bisschen besser zu erklären, was ich erreichen will.

Nehmen wir an, ich habe eine Liste:

["1234x4","253x4",2839",2845"]

Jetzt möchte ich alle Positionen der Zeichenfolgen, die Element 5 enthalten, zu einer neuen Liste hinzufügen. In einem aktuellen Beispiel wäre die Ergebnisliste:

[1,3]

Dafür habe ich eine ähnliche Funktion für elem ausgeführt:

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

Und Spring kann herausfinden, wie das Objekt initialisiert und das Repository über den Konstruktor eingefügt werden kann

Jetzt bekomme ich in meiner aktuellen Funktion die erste Elementposition, die das Element enthält, aber mein Kopf bleibt hängen, wie ich die vollständige Liste bekomme:

findBlock (x:xs) number arv =
  if myElem x number then arv else findBlock xs number arv+1

Wobei arv 0 ist und number die Nummer ist, nach der ich suche.

Zum Beispiel bei der Eingabe:

findBlock ["1234x4","253x4",2839",2845"] 5 0 

Das Ergebnis wäre 1

Jede Hilfe wäre dankbar.

2
Banana 3 Jän. 2016 im 21:30

3 Antworten

Beste Antwort

Eine Implementierung von findIndices zu Unterrichtszwecken:

findIndices ok list = f list 0 where
  f [] _ = []
  f (x:xs) ix
    | ok x      = ix : f xs (ix+1)
    | otherwise =      f xs (ix+1)

Verwenden Sie es wie findIndices (elem '5') my_list_o_strings

3
comingstorm 3 Jän. 2016 im 19:52

Die gewünschte Funktion ist bereits im Modul Data.List mit dem Namen findIndices vorhanden. Sie können einfach (elem '5') als Prädikat verwenden.

http://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#v:findIndices

Wenn Sie aus irgendeinem Grund die integrierte nicht verwenden dürfen, enthält sie eine sehr hübsche Definition (obwohl die tatsächlich verwendete eine kompliziertere und effizientere hat):

findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]

Übrigens habe ich diese Funktion gefunden, indem ich Hoogle nach dem Typ [a] -> (a -> Bool) -> [Int] durchsucht habe, der (Modulo-Parameterreihenfolge) offensichtlich der Typ ist, den eine solche Funktion haben muss. Der beste Weg, um aus Haskell herauszufinden, ist, über den Typ nachzudenken, den es haben müsste, und Hoogle oder Hayoo nach dem Typ zu durchsuchen. Hoogle ist IMO besser, da es einen leicht unscharfen Abgleich für den Typ bietet. z.B. Hayoo würde die Funktion hier nicht anhand des von mir angegebenen Typs finden, da die Argumente in umgekehrter Reihenfolge verwendet werden.

7
Will Ness 3 Jän. 2016 im 21:06

Dabei prüft {{X0}}, ob das markierte Element nicht 'x' oder '#' ist.

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

Dies nimmt eine Funktion und eine Liste und wendet die Funktion auf jeden Index und jedes Element an. Damit

mapWithIndex (\i x -> (i, x)) ['a', 'b', 'c'] =
[(0,'a'), (1,'b'),(2,'c')]

Sobald Sie dies getan haben, können Sie filter die Liste erstellen, um nur die gewünschten Paare zu erhalten:

filter (elem '5' . snd)

Und dann map fst darüber, um die Liste der Indizes zu erhalten.

Ein stärker integrierter Ansatz ist die Verwendung von 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)

So können Sie alles in einem Schritt erledigen.

Es stellt sich heraus, dass Sie foldrWithIndex mit foldr ziemlich ordentlich implementieren können, wodurch es für jeden Foldable Container verfügbar ist:

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))

Wie auch immer,

findIndices p = foldrWithIndex go [] where
  go i x r | p x = i : r
           | otherwise = r
1
dfeuer 3 Jän. 2016 im 20:52