如何在Ruby中获取数组的交集、并集和子集?

197
我想为名为Multiset的类创建不同的方法。
我已经准备好了所有必要的方法, 但是我不确定如何编写交集、并集和子集方法。
对于交集和并集,我的代码起始于:
def intersect(var)
  x = Multiset.new
end

这里是一个例子:
X = [1, 1, 2, 4]
Y = [1, 2, 2, 2]

那么XY的交集为[1, 2]


http://www.ruby-doc.org/core/classes/Array.html#method-M000274 - Krule
@Krule的链接已经失效,但我相信他是想指向数组“&”方法,可以在这里查看一些答案。 - rogerdpack
那个问题已经回答超过8年了。是的,那是交集,https://ruby-doc.org/core-2.6.3/Array.html#method-i-26 - Krule
如果(a-b).empty?,那么a是b的子集。 - Lori
3个回答

363

我假设XY是数组?如果是这样的话,有一种非常简单的方法来完成这个问题:

x = [1, 1, 2, 4]
y = [1, 2, 2, 2]

# intersection
x & y            # => [1, 2]

# union
x | y            # => [1, 2, 4]

# difference
x - y            # => [4]

来源


17
换句话说,只需执行“Multiset < Array”即可。 - sawa
如果你有以下代码: x = [1,1,2,4] y = [1,2,2,2] z = [4]如何获取它们之间任意集合的交集,而不是所有集合的交集? 因此,它会给出[1,2,4],而不是[]? - mharris7190
1
@mharris7190 你可以取所有这些交集的并集:(x & y) | (y & z) | (x & z) - xavdid
2
不要忘记还有&=,|=-=,如果你也想立即存储值的话! :) - Pysis
2
正是我想到的@sawa。为什么OP要首先创建这个类?它不做任何Ruby标准库中的数组已经存在的东西。 - danielricecodes
这很有趣 sawa - Wylliam Judd

163

利用数组上的集合操作,可以使用 &(交集)、-(差集)和 |(并集)。

显然,我没有按照规范实现 MultiSet,但这应该可以帮助你入门:

class MultiSet
  attr_accessor :set
  def initialize(set)
    @set = set
  end
  # intersection
  def &(other)
    @set & other.set
  end
  # difference
  def -(other)
    @set - other.set
  end
  # union
  def |(other)
    @set | other.set
  end
end

x = MultiSet.new([1,1,2,2,3,4,5,6])
y = MultiSet.new([1,3,5,6])

p x - y # [2,2,4]
p x & y # [1,3,5,6]
p x | y # [1,2,3,4,5,6]

9
这个答案有两个大错误: (1) 把 set 作为一个普通数组的变量名; (2) 复制已经由 Array 实现的所有功能。如果原帖想在 Array 类中添加一些额外方法的话,你应该这样做:class MultiSet < Array def inclusion?(other) Set.new(self).subset?(Set.new(other)) end end - Rahul Murmuria
1
同意...这可能是我一生中见过的最无用的课程...但我意识到这并不是你的错。 - mpowered

17
如果Multiset扩展自Array
x = [1, 1, 2, 4, 7]
y = [1, 2, 2, 2]
z = [1, 1, 3, 7]

联合

x.union(y)           # => [1, 2, 4, 7]      (ONLY IN RUBY 2.6)
x.union(y, z)        # => [1, 2, 4, 7, 3]   (ONLY IN RUBY 2.6)
x | y                # => [1, 2, 4, 7]

不同之处

x.difference(y)      # => [4, 7] (ONLY IN RUBY 2.6)
x.difference(y, z)   # => [4] (ONLY IN RUBY 2.6)
x - y                # => [4, 7]

交叉口

x.intersection(y)    # => [1, 2] (ONLY IN RUBY 2.7)
x & y                # => [1, 2]

如果您想了解有关Ruby 2.6中的新方法的更多信息,请查看此博客文章介绍其新功能


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接