TL;DR Die Werteseite ist
flat_map
denken--Wenn Sie alles in einer Tiefe von 2 oder mehr abflachen möchten
values.flatten
ist schnell, aber ich mag es, weil es sich nicht so sehr von each_value + flatten
unterscheidet.
Ausführungsumgebung 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) } #Das obige Beispiel ist auch mit Push anstelle von Concat in Ordnung
ary
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
sample.values.flatten
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
# ruby 2.Wenn es 7 ist,
sample.flat_map { _2 }
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
# _Wenn 2 nicht verwendet werden kann
sample.flat_map { |_, v| v }
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
# flat_Wenn Sie hier zeigen möchten, welchen Wert der Empfänger der Karte hat, ist es möglicherweise eine gute Idee, diese zu schreiben.
sample.flat_map { |_, number_ary| number_ary }
# => [1, 2, 3, 2, 3, 4, 3, 4, 5]
Wenn Sie den Wert von Tiefe 1 als flaches Array abrufen möchten
Die Ergebnisse sind wie folgt. (Da es die Häufigkeit ist, mit der die Schleife pro Sekunde gedreht werden kann, ist die große schneller.)
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
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
Wenn Sie alles in einer Tiefe von 2 abflachen und herausnehmen möchten
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
Es ist am schnellsten mit jedem_Wert zu tun. (Es unterscheidet sich nicht wesentlich von der Verwendung der einzelnen Werte, aber normalerweise ist jeder Wert unter Berücksichtigung der Lesbarkeit) Wenn es sich um flat_map handelt, ist der Rückgabewert der gewünschte Wert und es ist einfach, die Methodenkette fortzusetzen, aber es ist spät values.flatten ist ziemlich langsam
values.flatten
ist schneller, aber ähnlich wie each_value + flatten
.
Ausführungsumgebung Ruby 2.7.1
Recommended Posts