删除ruby中数组中的类似元素

gko*_*lan 0 ruby arrays swap

我有以下数组

a3 = [["a", "b"], ["a","c"], ["b","c"], ["b", "a"], ["c","b"]]
Run Code Online (Sandbox Code Playgroud)

我想得到以下输出[["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
Run Code Online (Sandbox Code Playgroud)

我尝试使用交换,但没有运气!

谢谢您的帮助.

Pat*_*ity 6

如果两个数组包含相同的元素并且这些元素的顺序相同,则认为它们是相等的:

["a", "b"] == ["b", "a"]
#=> false

["a", "b"] == ["a", "b"]
#=> true
Run Code Online (Sandbox Code Playgroud)

因此,您需要先对内部数组进行排序,然后Array#uniq才能确保外部数组中的每个元素只出现一次:

arr = [["a", "b"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
arr.map(&:sort).uniq
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
Run Code Online (Sandbox Code Playgroud)

arr但是,这将不受影响:

arr
#=> [["a", "b"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
Run Code Online (Sandbox Code Playgroud)

您将需要使用mutator方法(使用a !)来编辑数组:

arr = [["a", "b"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
arr.map!(&:sort).uniq!
arr
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
Run Code Online (Sandbox Code Playgroud)

编辑

作为@sawa评论的后续行动,谁担心改变内部数组的顺序可能不太可取,我看起来更深入了解Array#uniq.考虑以下数组:

arr = [["b", "a"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "b"]]
Run Code Online (Sandbox Code Playgroud)

我发现Array#uniq实际上需要一个块来指定元素应该如何比较:

arr.uniq!{|x| x.sort }
arr
#=> [["b", "a"], ["a", "c"], ["b", "c"]]
Run Code Online (Sandbox Code Playgroud)

很酷的是,这也适用于Symbol#to_proc(&:符号),实际上看起来比我原来的答案更优雅:

arr.uniq!(&:sort)
arr
#=> [["b", "a"], ["a", "c"], ["b", "c"]]
Run Code Online (Sandbox Code Playgroud)

Array#sort!如果您希望之后对内部数组进行排序,您仍然可以使用:

arr.uniq!(&:sort!)
arr
#=> [["a", "b"], ["a", "c"], ["b", "c"]]
Run Code Online (Sandbox Code Playgroud)

我对此的最后一个观察是,顺序可能并不重要,否则两个不同顺序的数组将被视为不相等.这让我思考(再次),我问自己一个问题:为什么不使用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"}>]
Run Code Online (Sandbox Code Playgroud)

请记住,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"}>]
Run Code Online (Sandbox Code Playgroud)