web-dev-qa-db-fra.com

ruby: somme des membres correspondants de deux ou plusieurs tableaux

J'ai deux tableaux (ou plus) de 12 entiers chacun (correspondant aux valeurs de chaque mois). Tout ce que je veux, c'est les additionner ensemble afin d'avoir un seul tableau avec des valeurs additionnées pour chaque mois. Voici un exemple avec trois valeurs: [1,2,3] et [4,5,6] => [5,7,9]

Le mieux que j'ai pu trouver était:

[[1,2,3],[4,5,6]].transpose.map{|arr| arr.inject{|sum, element| sum+element}} #=> [5,7,9]

Existe-t-il une meilleure façon de le faire? Cela semble tellement fondamental de vouloir faire.

34
jjnevis

Voici la version transpose proposée par Anurag:

[[1,2,3], [4,5,6]].transpose.map {|x| x.reduce(:+)}

Cela fonctionnera avec n’importe quel nombre de matrices de composants. reduce et inject sont des synonymes, mais reduce me semble communiquer plus clairement l'intention du code ici ...

47
glenn mcdonald

Pour une syntaxe plus claire (pas la plus rapide), vous pouvez utiliser Vector:

require 'matrix'
Vector[1,2,3] + Vector[4,5,6]
=> Vector[5, 7, 9]

Pour plusieurs vecteurs, vous pouvez faire:

arr = [ Vector[1,2,3], Vector[4,5,6], Vector[7,8,9] ]
arr.inject(&:+)
=> Vector[12, 15, 18]

Si vous souhaitez charger vos tableaux en vecteurs et résumer:

arrays = [ [1,2,3], [4,5,6], [7,8,9] ]
arrays.map { |a| Vector[*a] }.inject(:+)
=> Vector[12, 15, 18]
8
Abdo

voici ma tentative de code-golf cette chose:

// Ruby 1.9 syntax, too bad they didn't add a sum() function afaik
[1,2,3].Zip([4,5,6]).map {|a| a.inject(:+)} # [5,7,9]

Zip renvoie [1,4], [2,5], [3,6] et mappe la somme de chaque sous-tableau.

7
Anurag

Je pense humblement que les autres réponses que je vois sont si complexes qu'elles semeraient la confusion chez les réviseurs de code. Vous devez ajouter un commentaire explicatif, ce qui augmente simplement la quantité de texte nécessaire.

Comment ça à la place:

a_arr = [1,2,3]
b_arr = [4,5,6]
(0..2).map{ |i| a_arr[i] + b_arr[i] }

Solution légèrement différente: (pour ne pas coder "2" en dur)

a_arr = [1,2,3]
b_arr = [4,5,6]
c_arr = []
a_arr.each_index { |i| c_arr[i] = a_arr[i] + b_arr[i] }

Enfin, mathématiquement parlant, c’est la même question que celle-ci:

Comment effectuer une addition vectorielle dans Ruby?

5
Brandon Meredith
[[1,2,3],[4,5,6]].transpose.map{|a| a.sum} #=> [5,7,9]
5
user2061694

Maintenant nous pouvons utiliser sum in 2.4

nums = [[1, 2, 3], [4, 5, 6]]
nums.transpose.map(&:sum) #=> [5, 7, 9]
4
cavin kwon

Pour:

a = [1,2,3]
b = [4,5,6]

Vous pouvez Zip puis utiliser reduce:

p a.Zip(b).map{|v| v.reduce(:+) }
#=> [5, 7, 9]

Ou, si vous êtes certain que les tableaux a et b seront toujours de même longueur:

p a.map.with_index { |v, i| v + b[i] }
#=> [5, 7, 9]
1
Surya

@FriendFX, vous avez raison sur la réponse de @ user2061694. Cela ne fonctionnait que dans l'environnement Rails pour moi. Vous pouvez le faire fonctionner en Ruby si vous apportez les modifications suivantes:.

À la CISR

[[0, 0, 0], [2, 2, 1], [1,3,4]].transpose.map {|a| a.inject(:+)}
 => [3, 5, 5]


[[1,2,3],[4,5,6]].transpose.map {|a| a.inject(:+)}
 => [5, 7, 9]
1
cevaris

Ce n'est peut-être pas la meilleure réponse mais cela fonctionne.

array_one = [1,2,3]
array_two = [4,5,6]
x = 0
array_three = []
while x < array_one.length
  array_three[x] = array_one[x] + array_two[x]
  x += 1
end

=>[5,7,9]

Cela pourrait être plus de lignes de code que d'autres réponses, mais c'est quand même une réponse

0
Johnson