我有以下数组
a3 = [["a", "b"], ["a","c"], ["b","c"], ["b", "a"], ["c","b"]]
我想获得以下输出[["a","b"], ["a","c"], ["b","c"]]
并删除["b","a"] and ["c","b"]
我有以下代码
a3.each do |ary3|
x = ary3[0]
y = ary3[1]
x = ary3[1]
y = ary3[0]
if a3.include?([x,y])
a3 - [y,x]
end
end
print a3
我尝试使用交换,但没有运气!
感谢您的帮助。
答案 0 :(得分:6)
如果两个数组包含相同的元素并且这些元素的顺序相同,则认为它们是相等的:
["a", "b"] == ["b", "a"]
#=> false
["a", "b"] == ["a", "b"]
#=> true
因此,您需要先对内部数组进行排序,然后使用Array#uniq
确保外部数组中的每个元素只出现一次:
arr = [["a", "b"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
arr.map(&:sort).uniq
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
然而,这将使arr
保持不变:
arr
#=> [["a", "b"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
您需要使用mutator方法(使用!
)来编辑数组:
arr = [["a", "b"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
arr.map!(&:sort).uniq!
arr
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
作为@sawa评论的后续行动,谁担心改变内部数组的顺序可能不合适,我看起来更深入Array#uniq
。请考虑以下数组:
arr = [["b", "a"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
我发现Array#uniq
实际上需要一个块来指定元素应该如何比较:
arr.uniq!{|x| x.sort }
arr
#=> [["b", "a"], ["a", "c"], ["b", "c"]]
很酷的是,这也适用于Symbol#to_proc
(&:
符号),实际上看起来比我原来的答案更优雅:
arr.uniq!(&:sort)
arr
#=> [["b", "a"], ["a", "c"], ["b", "c"]]
如果您希望事后对内部数组进行排序,您仍然可以使用Array#sort!
:
arr.uniq!(&:sort!)
arr
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
我对此的最后一个观察是,顺序可能并不重要,否则两个不同顺序的数组将被视为不相等。这让我思考(再次),我自己提出了一个问题:为什么不使用Set
?它会像这样工作:
require 'set'
sets = [Set["a", "b"], Set["a", "c"], Set["b", "c"], Set["b", "a"], Set["c", "b"]]
sets.uniq!
sets
#=> [#<Set: {"a", "b"}>, #<Set: {"a", "c"}>, #<Set: {"b", "c"}>]
请记住,Set不允许多次添加相同的元素,而数组则会:
[%w[a b b b c], %w[a b b b c], %w[a b c]].uniq(&:sort)
#=> [["a", "b", "b", "b", "c"], ["a", "b", "c"]]
[Set.new(%w[a b b b c]), Set.new(%w[a b b b c]), Set.new(%w[a b c])].uniq
#=> [#<Set: {"a", "b", "c"}>]
答案 1 :(得分:0)
检查一下:#delete_if
如下:
a3 = [["a", "b"], ["a","c"], ["b","c"], ["b", "a"], ["c","b"]]
p a3.delete_if{|x| [["b", "a"], ["c","b"]].include? x}
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
根据您的评论和说明帖子:
a3 = [["a", "b"], ["a","c"], ["b","c"], ["b", "a"], ["c","b"],["b", "a"]]
p a3.each {|x| a3.delete(x.reverse) if a3.include? x.reverse}
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
的基准:强> 的
require 'benchmark'
N = 10000
Benchmark.bm(20) do | x |
a3 = [["a", "b"], ["a","c"], ["b","c"], ["b", "a"], ["c","b"],["b", "a"]]
x.report('Mine') do
N.times { a3.each {|x| a3.delete(x.reverse) if a3.include? x.reverse} }
end
a3 = [["a", "b"], ["a","c"], ["b","c"], ["b", "a"], ["c","b"],["b", "a"]]
x.report('padde') do
N.times { a3.uniq!(&:sort!) }
end
end
的输出:强> 的
user system total real
Mine 0.172000 0.000000 0.172000 ( 0.361021)
padde 0.203000 0.000000 0.203000 ( 0.460026)