1
votes

MULTIPLIER un ELEMENT de tableau dans la boucle while ruby

J'ai un tableau d'entiers et j'essaye de multiplier chaque deuxième élément par 2 en reculant dans le tableau. Cependant, il ne semble pas accepter l'opérateur * sur l'élément du tableau, entraîne le message d'erreur: méthode non définie `* 'pour nil: NilClass (NoMethodError)

 index = array.length
  while index > 0
    array[index] * 2
    index - 2
  end

J'ai vérifié la classe des éléments du tableau et c'est en effet un entier, donc je ne sais pas pourquoi cela ne fonctionne pas.

Merci.


5 commentaires

Vous ne faites rien avec la valeur de vos expressions array [index] * 2 et index - 2 , vous devez les affecter à quelque chose: array [ index] * = 2 , array [index] = array [index] * 2 , index = index - 2 , index - = 2 < / code>, ...


essayé de faire cela, entraîne toujours une "méthode non définie` * 'pour nil: NilClass (NoMethodError) "


c'est un tableau d'entiers: [4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2]


votre index doit être array.length - 1 (rappelez-vous, les tableaux sont indexés à 0). De plus, vous ne faites rien avec array [index] * 2 (soit l'imprimer, soit l'assigner à une variable)


Avec un tableau d'entrée de [4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2] , à quoi vous attendiez-vous la sortie à être? J'avais interprété l'expression "chaque deuxième élément" comme signifiant que le résultat devrait être [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] . Est-ce correct?


4 Réponses :


1
votes

Vous pouvez parcourir un tableau inversé avec des index, puis inverser le résultat Array # reverse i% 3 est utilisé pour multiplier chaque 3ème élément.

L'erreur méthode non définie * 'pour nil: NilClass (NoMethodError) dans votre exemple apparaît car array.length est 16 (éléments dans le tableau), mais les index commencent à 0 , donc le dernier index est 15, et dans la première itération, vous essayez d'accéder au tableau [16] qui n'existe pas, donc c'est nil

array = [4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 99]
p array.map.with_index { |n, i| i.odd? ? n * 2 : n } # WRONG RESULT
#=>[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 99]
p array.reverse.map.with_index { |n, i| i.even? ? n * 2 : n }.reverse
#=>[8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 198]

MISE À JOUR: La réponse de Sekalf Nroc est bonne avec impair? si vous avez besoin que chaque 2ème élément se multiplie, mais si vous aviez par exemple 15 éléments, vous pourriez voir de l'inattendu résultats, donc reverse encore nécessaire pour faire reculer le tableau, en combinant ces approches, vous pouvez faire quelque chose comme ceci:

array = [4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2]
result = array.reverse.each_with_index.map do |x, i|
  (i % 3).zero? ? x * 2 : x
end.reverse
# p result
#=> [8, 2, 4, 4, 4, 2, 8, 2, 4, 4, 4, 2, 8, 2, 4, 4]


0 commentaires

1
votes

Si vous corrigez l'indexation comme d'autres l'ont suggéré, et modifiez les troisième et quatrième lignes pour modifier réellement les variables de tableau et d'index, alors votre code fonctionne comme prévu pour tout tableau avec un nombre pair d'éléments.

array.map.with_index { |n, i| i.odd? ? n * 2 : n }
# Or if you prefer,
array.map.with_index { |n, i| if i.odd? then n * 2 else n end }

#=> [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]

Vous pouvez également effectuer l'opération sur une ligne en utilisant map.with_index en profitant du fait que chaque deuxième élément d'un tableau aura un index qui est un nombre impair.

index = array.length - 1
while index > 0
  array[index] *= 2
  index -= 2
end

# array now =='s [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]


0 commentaires

0
votes

Vous pouvez utiliser une plage, qui fournit le Méthode Range # step . Par exemple, étant donné le tableau:

#=> [1, 3, 5, 7, 9, 11, 13, 15]

C'est un moyen pour "multiplier chaque deuxième élément par 2 en reculant dans le tableau" en utilisant Array # reverse_each :

(1...ary.size).step(2).each { |i| ary.size.odd? ? ary[i] *=2 : ary[i-1] *=2 }
#=> [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]

Notez que la première partie (1 ... ary.size) .step (2) .to_a renvoie les index impairs:

ary = [4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2]

Notez également les trois pointe ... dans la plage.

Pour ary = [2, 4, 2] # => [2, 8, 2] p>

Pour ary = [2, 4, 2, 4] # => [4, 4, 4, 4]


3 commentaires

Bonne approche, mais ce n'est pas une solution universelle, essayez avec [2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2]


@YuriyVerbitskiy, merci. Corrigé, j'ai mal interprété l'OP. Même si j'ai encore un doute.


J'ai essayé Numeric # step et ajouté une nouvelle réponse, cela semble être un meilleur moyen de l'utiliser dans ce cas