Carte un tableau en modifiant uniquement les éléments correspondant à une certaine condition
En Ruby, ce qui est le plus expressif pour cartographier un tableau de telle manière que certains éléments sont modifiés et les autres laissés intacts?
C'est une simple façon de le faire:
old_a = ["a", "b", "c"] # ["a", "b", "c"]
new_a = old_a.map { |x| (x=="b" ? x+"!" : x) } # ["a", "b!", "c"]
En omettant le "laissez-le seul" cas bien sûr, si pas assez:
new_a = old_a.map { |x| x+"!" if x=="b" } # [nil, "b!", nil]
Ce que je voudrais, c'est quelque chose comme ceci:
new_a = old_a.map_modifying_only_elements_where (Proc.new {|x| x == "b"})
do |y|
y + "!"
end
# ["a", "b!", "c"]
Est-il une bonne façon de le faire en Ruby (ou peut-être Rails a une sorte de méthode de convenance que je n'ai pas encore trouvé)?
Merci à tous pour la réponse. Alors que vous avez collectivement m'a convaincu qu'il est préférable d'utiliser map
avec l'opérateur ternaire, certains d'entre vous posté des réponses très intéressantes!
- Je pense que le #map chose est très bien comme il est. 😉
- Ouais, je suis d'accord. Vous pouvez prendre les parens si ça fait de vous l'aimez plus!
- Fermé? FTL. Regarde mon post =P
- Je suis venu ici à la recherche d'un moyen de ne retenir que certains éléments, et j'ai trouvé cela très utile: stackoverflow.com/questions/5152098/...
Vous devez vous connecter pour publier un commentaire.
Je suis d'accord que la carte de déclaration est bon qu'il est. Il est clair et simple, et serait facile de
pour quiconque de maintenir.
Si vous voulez quelque chose de plus complexe, comment à ce sujet?
Car les tableaux sont des pointeurs, cela fonctionne aussi:
Dans la boucle, assurez-vous d'utiliser une méthode qui modifie l'objet plutôt que de créer un nouvel objet. E. g.
upcase!
par rapport àupcase
.La procédure exacte dépend exactement ce que vous essayez d'atteindre. Il est difficile de clouer une réponse définitive avec foo-bar exemples.
donne
map!
modifie le récepteur en place, de sorteold_a
est maintenant que le tableau retourné.Votre
map
solution est la meilleure. Je ne suis pas sûr de savoir pourquoi vous pensez map_modifying_only_elements_where est en quelque sorte mieux. À l'aide demap
est plus propre, plus concis, et ne nécessite pas plusieurs blocs.Un liner:
Dans le code ci-dessus, vous commencez avec [] "cumulative". Comme vous énumérer par un agent Recenseur (dans notre cas, la matrice, ["a", "b", "c"]), cumulatifs ainsi que "l'actuel" élément se passait à notre bloc (cumulative, j'|) et le résultat de notre bloc de l'exécution est attribué à cumulatifs. Ce que je fais ci-dessus est de garder cumulatif inchangé lorsque l'élément n'est pas de "b" et d'ajouter "b!" à l'ensemble de la matrice et de le retourner quand c'est un b.
Il n'y est une réponse ci-dessus qui utilise
select
, qui est le moyen le plus facile à faire (et rappelez-vous) c'.Vous pouvez combiner
select
avecmap
afin d'obtenir ce que vous cherchez:À l'intérieur de la
select
bloc, vous spécifiez les conditions pour qu'un élément soit "sélectionné". Cela va retourner un tableau. Vous pouvez appeler la "carte" sur le tableau pour ajouter le point d'exclamation à elle.Si vous n'avez pas besoin de l'ancien tableau, je préfère le une carte! dans ce cas, car vous pouvez utiliser la ! méthode pour vous représenter sont en train de changer le réseau en place.
Je préfère ce sur:
C'est quelques lignes de long, mais voici une autre pour l'enfer de celui-ci:
La recueillir avec ternaire semble la meilleure à mon avis.
J'ai trouvé que la meilleure façon d'y parvenir est par l'utilisation de
tap