如何使用ruby从此数组中获取所有元素?

时间:2018-10-23 09:21:25

标签: arrays ruby

想要从这种类型的数组中获取所有唯一ID:

[[], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2]]

3 个答案:

答案 0 :(得分:8)

给出a您的数组

a.flatten.uniq

答案 1 :(得分:2)

[[], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2]].
  reduce([]) { |acc, e| acc | e }
  # or (credit goes to @Stefan)
  # reduce([], :|)

#⇒ [1, 2, 3, 4, 5, 6, 7, 8]

答案 2 :(得分:1)

为了完整起见,请使用微基准测试来显示另一个解决方案:使用uniq!的就地版本,它会稍快一些。

如果可以更改原始数组,也可以使用

array.flatten! array.uniq! 但请注意,这会修改array,并且这可能是不需要的,尤其是对于方法而言。

这是一个微型基准:

require "benchmark/ips"
# ARRAY = [[], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2]].freeze
ARRAY = [[], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2], [], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2], [], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2], [], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2],[], [1], [2], [1, 3, 2], [4, 5, 6, 7, 8, 1], [2, 4], [3], [2]].freeze

Benchmark.ips do |x|
    x.compare!

    x.report("flatten.uniq") { ARRAY.flatten.uniq }
    x.report("flatten.uniq!") { ARRAY.flatten.uniq! }
    x.report("reduce") { ARRAY.reduce([]) { |acc, e| acc | e } }
end

结果如下:

Comparison:
       flatten.uniq!:   107888.3 i/s
        flatten.uniq:   105813.6 i/s - same-ish: difference falls within error
              reduce:    49892.6 i/s - 2.16x  slower

请注意,如果元素较少,则reduce变体实际上可能会更快。但是它仅适用于一个级别的嵌套,而其他版本则适用于所有级别。因此[[[1]]]不能与reduce变体一起使用。