2012-10-26 77 views
2

我必须找到3个整数阵列的交集元素 说a,b,c与条件;如果任何数组为空([]), 只是简单地忽略该数组并找到剩余数组的交集 ,并且如果所有三个都为null,则返回[]。 在此先感谢。如何找到3个数组的交集,而忽略空数组?

PS:红宝石1.9.3

+1

你可以发布一些示例数组和预期结果吗? – agmin

+0

一个= [] B = [1,2] C = [2] 结果= [2] –

+0

@tokland 很奇怪:P' 我 = -1 I + = 1,如果a.present? i + = 1 if b.present? i + = 1如果c.present? res =(a + b + c) res.select {| e | res.count(e)> i}' –

回答

4

一种方式做到这一点会是这样:

[ a, b, c ].tap{ |a| a.delete([]) }.reduce(:&) || [] 

在讨论中提出的其他选项有:

[ a, b, c ].reject(&:empty?).reduce(:&) || [] 

和:

[ a, b, c ].select(&:any?).reduce(:&) || [] 

但是在最后的cas e,注意带有显式nil元素的非空数组,例如[ nil ],导致它们仍然失败#any?测试。

+3

'tap {| a | a.delete([])':也许最好只是拒绝(&:空?)'。 – steenslag

+0

你说得对。那会更漂亮。请您编辑我的答案以显示您的额外选项? –

+1

很好的答案,但我会替换'.tap {| a | a.delete([])}'with'.select(&:any?)' – ndbroadbent

-1

有可能这样做的更简洁的手段,但这应该得到你所需要的。

def intersection(*arrays) 
    # Reduce the list of arrays to only the ones with elements 
    arrays = arrays.select(&:first) 

    return [] if arrays.empty? 

    # Grab the first array 
    intersection = arrays.pop 

    # Iterate over the arrays finding the intersection 
    arrays.each do |array| 
    intersection = intersection & array 
    end 

    # Return the resultant array 
    intersection 
end 

UPDATE

我知道有所有的数组中元素的应用之间的操作方法,但由于某些原因,我错过了reduce看在阵列文档时。 reduce肯定是要走的路:

arrays.reject(&:empty?).reduce(&:&) 
+0

首先,操作符不需要&符号&:&',':&'就足够了。其次,你显然无法在Array文档中遇到#reduce,因为它是Enumerable mixin方法,因此可用于所有集合,而不仅仅是数组。我赞扬你的努力。 –

+0

@ boris-stitnicky呵呵,你只需要':&'?我没有意识到这一点。这是1.9.x的变化,还是一直如此? – brentmc79

+0

我认为它来自1.9.x.例如,要总结从1到10的数字,现在可以编写'[* 1..10] .reduce(:+)'。 –

0
[a, b, c].reject(&:blank?).reduce(:&) 
+0

别忘了'require'active_support/core_ext/object/blank'' –