我是Ruby的新手,并且希望能够在两个数组之间找到差异.
我知道通常的方法:
a = [...] b = [...] difference = (a-b)+(b-a)
但问题在于这是计算集合的差异,因为在ruby中,语句(a-b)
定义了相对于b的集合恭维.
这意味着[1,2,2,3,4,5,5,5,5] - [5]
= [1,2,2,3,4]
,因为它取出了第一组中出现的所有5个,而不仅仅是一个,表现得像数据上的过滤器.
我希望它只删除一次差异,例如,差异[1,2,2,3,4,5,5,5,5]
,并且[5]
应该只[1,2,2,3,4,5,5,5]
删除一个5.
我可以迭代地做到这一点:
a = [...] b = [...] complimentAbyB = a.dup complimentBbyA = b.dup b.each do |bValue| complimentAbyB.delete_at(complimentAbyB.index(bValue) || complimentAbyB.length) end a.each do |aValue| complimentBbyA.delete_at(complimentBbyA.index(aValue) || complimentBbyA.length) end difference = complimentAbyB + complimentBbyA
但这看起来非常冗长和低效.我不得不想象有一个更优雅的解决方案.所以我的问题基本上是,找到两个数组的差异的最优雅的方法是什么,如果一个数组出现单个元素然后另一个数组,它们将不会被删除?
我最近提出将这种方法,Ruby#的差异,添加到Ruby的核心.对于你的例子,它将写成:
a = [1,2,2,3,4,5,5,5,5] b = [5] a.difference b #=> [1,2,2,3,4,5,5,5]
我经常给出的例子是:
a = [3,1,2,3,4,3,2,2,4] b = [2,3,4,4,3,4] a.difference b #=> [1, 3, 2, 2]
我在这里的答案中首先提出了这种方法.在那里你会找到一个解释和其他SO问题的链接,我建议使用这个方法.
如链接所示,该方法可以写成如下:
class Array def difference(other) h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 } reject { |e| h[e] > 0 && h[e] -= 1 } end end