TL;DR Le côté valeur est
--Profondeur 1
La vitesse la plus rapide est each_value
Si vous voulez continuer la chaîne de méthodes, vous pouvez penser à flat_map
values.flatten
est rapide, mais je l'aime parce que ce n'est pas aussi rapide que each_value + flatten
.Environnement d'exécution Ruby 2.7.1
sample = { a: [1, 2, 3], b: [2, 3, 4], c: [3, 4, 5] }
ary = []
sample.each { |_k, v| ary.concat(v) }
ary
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
ary = []
sample.each_value { |v| ary.push(*v) } #L'exemple ci-dessus convient également avec push au lieu de concat
ary
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
sample.values.flatten
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
# ruby 2.Si c'est 7,
sample.flat_map { _2 }
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
# _Si 2 ne peut pas être utilisé
sample.flat_map { |_, v| v }
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
# flat_Si vous voulez montrer ici quelle est la valeur du récepteur de la carte, je pense que ce peut être une bonne idée de l'écrire.
sample.flat_map { |_, number_ary| number_ary }
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
Lorsque vous souhaitez récupérer la valeur de la profondeur 1 sous la forme d'un tableau plat
Les résultats sont les suivants. (Comme c'est le nombre de fois que la boucle peut être tournée par seconde, la grande est plus rapide)
Comparison:
each_value: 2859228.9 i/s
each concat: 2745728.9 i/s - same-ish: difference falls within error
flat_map(_,v): 1986117.7 i/s - 1.44x (± 0.00) slower
flat_map(_2): 1971975.8 i/s - 1.45x (± 0.00) slower
values flatten: 918971.6 i/s - 3.11x (± 0.00) slower
<détails> Lorsque vous voulez tout aplatir à une profondeur de 2 et le retirer <détails> C'est le plus rapide à faire avec each_value. (Ce n'est pas très différent de l'utilisation de chacun, mais c'est généralement each_value compte tenu de la lisibilité)
Si c'est flat_map, la valeur de retour sera la valeur souhaitée et il est facile de continuer la chaîne de méthodes, mais il est tard
values.flatten est assez lent Environnement d'exécution Ruby 2.7.1
Recommended Posts
require 'benchmark/ips'
sample = { a: [1, 2, 3], b: [2, 3, 4], c: [3, 4, 5] }
def method_1(h)
ary = []
h.each { |_k, v| ary.concat(v) }
ary
end
def method_2(h)
ary = []
h.each_value { |v| ary.push(*v) }
ary
end
def method_3(h)
h.values.flatten
end
def method_4(h)
h.flat_map { _2 }
end
def method_5(h)
h.flat_map { |_, v| v }
end
Benchmark.ips do |x|
x.config(:time => 20, :warmup => 2)
x.report("each concat") { method_1(sample) }
x.report("each_value ") { method_2(sample) }
x.report("values flatten") { method_3(sample) }
x.report("flat_map(_2)") { method_4(sample) }
x.report("flat_map(_,v)") { method_5(sample) }
x.compare!
end
Test 2
Comparison:
values flatten: 800647.1 i/s
each_value.flatten: 759526.1 i/s - 1.05x (± 0.00) slower
flat_map flatten: 676500.5 i/s - 1.18x (± 0.00) slower
each_value in flatten: 468859.1 i/s - 1.71x (± 0.00) slower
require 'benchmark/ips'
sample = { a: [1, 2, [3]], b: [2, 3, [4]], c: [3, 4, [5]] }
def method_1(h)
ary = []
h.each_value { |v| ary.push(*v.flatten) }
ary
end
def method_2(h)
ary = []
h.each_value { |v| ary.push(*v) }
ary.flatten
end
def method_3(h)
h.values.flatten
end
def method_4(h)
h.flat_map { _2 }.flatten
end
Benchmark.ips do |x|
x.config(:time => 20, :warmup => 2)
x.report("each_value in flatten") { method_1(sample) }
x.report("each_value.flatten") { method_2(sample) }
x.report("values flatten") { method_3(sample) }
x.report("flat_map flatten") { method_4(sample) }
x.compare!
end
Conclusion
En profondeur 1
Lorsque vous voulez que tout soit plat à une profondeur de 2 ou plus
values.flatten
est plus rapide, mais il est similaire à each_value + flatten
.