12
votes

Supprimer les éléments par index dans HASKELLL

Je suis nouveau à Haskell et je recherche des fonctions standard pour travailler avec des listes par index.

Mon problème exact est que je veux supprimer 3 éléments après chaque 5. Si ce n'est pas assez clair ici, il est d'illustration: xxx

Je sais écrire une énorme fonction avec De nombreux paramètres, mais y a-t-il un moyen intelligent de faire cela?


1 commentaires

Oui, g n m = carte prise m. M surmainement (pas.Null). Définissez (juste. Splithat (n + m)) et l'appelez comme g 3 5 "YÇON" . Import data.list pour le se déroule .


8 Réponses :


5
votes

Vous pouvez compter facilement vos éléments:

strip (a:b:c:d:e:_:_:_:xs) = a:b:c:d:e:strip xs
strip (a:b:c:d:e:xs) = a:b:c:d:e:[]
strip xs = xs


2 commentaires

J'aime la deuxième version, mais ce n'est pas généralisciabe. Ce qui est malheureux, car il est peut-être la solution la plus claire ici.


J'aime la solution de correspondance de modèle. Simple comme cela peut être possible. Bien que vous ayez besoin d'autres pour correspondre à des listes de moins de huit éléments. Ne peut jamais se rappeler comment cela fonctionne.



1
votes

Voici ma solution: xxx

exemple: xxx


0 commentaires

2
votes

Le prend code> et Drop code> Les fonctions peuvent être capables de vous aider ici.

takeEveryNafterEveryM2 n m = splitReduce (takeNdropM 5 3)


0 commentaires

17
votes

Deux approches complètement différentes
  1. Vous pouvez utiliser list.splitatat code> avec goutte code> : p>

    nofm :: Int -> Int -> [a] -> [a]
    nofm n m = map snd . filter (\(i, _) -> i `mod` m < n) . zip [0..]
    


1 commentaires

+1 Solution Deux est facilement généralisable à NOFM :: INT -> INT -> [A] -> [A] Prendre deux arguments à mettre à la place de 8 et 5, respectivement. Cela a également l'avantage d'être très clairement nommé.



2
votes

C'est ma solution. C'est beaucoup comme @ Réponse de Barkmadley , en utilisant uniquement prendre et goutte , mais avec moins d'encombrement à mon avis: xxx

Je ne sais pas si ça va gagner des récompenses de vitesse ou d'intelligence, mais Je pense que c'est assez clair et concis, et cela fonctionne certainement: xxx


0 commentaires

1
votes
myRemove = map snd . filter fst . zip (cycle $ (replicate 5 True) ++ (replicate 3 False))

0 commentaires

4
votes

Puisque personne n'a fait une version avec "déroulée", voici ma prise:

drop3after5 lst = concat $ unfoldr chunk lst
  where
    chunk [] = Nothing
    chunk lst = Just (take 5 lst, drop (5+3) lst)


1 commentaires

La fonction de concession est nécessaire au résultat final.



12
votes

Voici ma prise:

deleteAt idx xs = lft ++ rgt
  where (lft, (_:rgt)) = splitAt idx xs


0 commentaires