Supprimer des éléments à l'index en haskell
Je suis nouveau dans haskell et je suis à la recherche de quelques fonctions standard pour travailler avec des listes, index.
Mon problème est que je veux supprimer 3 éléments après chaque 5. Si elle n'est pas assez clair ici est l'illustration:
OOOOOXXXOOOOOXXX...
Je sais comment écrire énorme fonction de nombreux paramètres, mais est-il une manière intelligente de faire cela?
- oui,
g n m = map take m . takeWhile (not.null) . unfoldr (Just . splitAt (n+m))
et l'appeler commeg 3 5 "yourstring"
. importationData.List
pour launfoldr
.
InformationsquelleAutor qba | 2009-11-14
Vous devez vous connecter pour publier un commentaire.
Deux choses complètement différentes approches
Vous pouvez utiliser
Liste.splitAt
avecgoutte
:Maintenant
f [1..12]
rendements[1,2,3,4,5,9,10,11,12]
. Notez que cette fonction peut être exprimée de manière plus élégante à l'aide deuncurry
etde Contrôle.Flèche.deuxième
:Puisque nous l'utilisons
de Contrôle.Flèche
de toute façon, on peut choisir de déposersplitAt
et au lieu d'appeler à l'aide dede Contrôle.Flèche.(&&&)
, combiné avecprendre
:Mais maintenant, il est clair qu'une encore plus petite solution est la suivante:
Comme Chris Lutz notes, cette solution peut donc être généralisée comme suit:
Maintenant
nofm 5 8
les rendements de la fonction requise. Notez qu'une solution avecsplitAt
peut-être encore plus efficace!Appliquer un peu de mathématiques à l'aide de
map
,snd
,filtre
,mod
etzip
:L'idée ici est que nous paire chaque élément dans la liste avec son index, un nombre naturel je. Nous avons ensuite supprimer les éléments pour lesquels j' % 8 > 4. La version générale de cette solution est:
NofM :: Int -> Int -> [a] -> [a]
prenant deux arguments à mettre en place de 8 et 5, respectivement. Il a aussi l'avantage d'être assez clairement nommé.Ici est mon point de vue:
Depuis personne ne l'a fait une version avec "unfoldr", ici, est de mon point de vue:
Semble être la plus courte jusqu'à présent
Vous pouvez compter vos éléments facilement:
Si open-codage semble plus courte:
la
take
etdrop
fonctions peuvent être en mesure pour vous aider ici.de ces nous avons pu construire une fonction pour faire une étape.
et puis on peut l'utiliser pour réduire notre problème
puisque ce n'est pas une forme primitive de la récursivité, il est plus difficile d'exprimer cela comme un simple pli.
donc une nouvelle fonction de pliage peut être défini pour s'adapter à vos besoins
alors, la définition de
takeEveryNafterEveryM
est tout simplementC'est ma solution. C'est un peu comme @barkmadley réponse, en utilisant uniquement
take
etdrop
, mais avec moins d'encombrement dans mon opinion:Ne sais pas si il va gagner un prix pour la vitesse ou de l'astuce, mais je pense que c'est assez clair et concis, et il est certainement fonctionne:
Voici ma solution:
exemple: