你如何缩小一系列阵列?

时间:2011-04-04 17:51:53

标签: ruby-on-rails ruby arrays

我有几个数组。我想缩小它们的范围,以便在最后,无论出现什么,只要这些数组不是零,就可以在所有其他数组中看到这些值。

我对编码的悲惨尝试:

array_of_users = []
array_of_users & @zip_ids if !@zip_ids.empty?
array_of_users & @sex_ids if !@sex_ids.empty?
array_of_users & @interest_ids if !@interest_ids.empty?
array_of_users & @age_ids if !@age_ids.empty?

逻辑上,我会认为这会起作用,因为只要它不是空的,它就会找到每个相似之处,但实际上并没有将它们添加到数组中。

你将如何实现这一目标?

6 个答案:

答案 0 :(得分:2)

我想你想要这个:

users = [@zip_ids,@sex_ids,@interest_ids,@age_ids].reject(&:empty?).reduce(&:&)

答案 1 :(得分:2)

以这种方式思考:

  

([1] | [2] | [3,4])& [3,4]

     

=> [3,4]

所以你可以这样做:

  

array_of_users = @zip_ids | @sex_ids | @interest_ids | @age_ids

     

intersection = array_of_users& @zip_ids& @sex_ids& @interest_ids& @age_ids

只有像@glenn所说的那样,它忽略了“不合并,如果空”的要求。

@DigitalRoss很好,但是如果第一个数组是空的,那么一切都会变平。

然后,来自@glenn:

  

[[],[1,2],[2],[2,3,4,4],[]]拒绝(安培;:空?)降低。(安培;:&安培;)

     

=> [2]

答案 2 :(得分:1)

您需要将它们实际分配给数组。在您的代码所处的位置,您正在进行交集,但您实际上并未将它们分配给数组。你需要在那里添加='s运算符。

以下是一个示例设置:

>> x = [ 1, 1, 3, 5 ] 
>> y = [ 1, 2, 3 ]

这就是你现在正在做的事情:

>> x & y
=> [1, 3]
>> x
=> [1, 1, 3, 5]

这是它需要去的地方:

>> x &= y
=> [1, 3]
>> x
=> [1, 3]

因此,这应该完成工作:

array_of_users = []
array_of_users &= @zip_ids if !@zip_ids.empty?
array_of_users &= @sex_ids if !@sex_ids.empty?
array_of_users &= @interest_ids if !@interest_ids.empty?
array_of_users &= @age_ids if !@age_ids.empty?

希望这会有所帮助 - 旁注:我在IRB(交互式红宝石外壳)中完成了所有这些工作。这是你的朋友。 :)

答案 3 :(得分:1)

[@z, @s, @i, @a].reject(&:empty?).inject { |m, e| m & e }

答案 4 :(得分:0)

正如您可以阅读here方法数组#&返回一个新数组并且不会修改原始数组,因此您必须将代码更改为:

假设你想要所有四个非空数组中包含的ID,我会尝试这样的事情:

ary = []
ids = [@zip_ids, @sex_ids, @interest_ids, @age_ids]
ids.each {|i|ary << i unless i.empty?}
ary.uniq!
result = ids.inject(ary){|res, ids| res & ids}

答案 5 :(得分:0)

正如格伦所说,最常用的方法可能是

users = [@zip_ids, @sex_ids, @interest_ids, @age_ids].reject(&:empty?).reduce(&:&)

但是,这取决于#hash和#eql的行为?对于数组中的对象。由于Object#hash的实现基于object_id,所以Array#&amp;对于User对象(可能使用默认的Object #hash impl)将比较对象id,而不是定义对象的等式语义的任何值。

允许您比较User对象的数组而不仅仅是它们的id的解决方案是定义#hash和#eql?对象的语义,然后使用数组#&amp;。例如:

class User
  # ...

  def hash
    [self.class, *equality_attributes].map(&:hash).reduce(:^)
  end

  def eql?(other)
    self.class == other.class &&
      self.equality_attributes == other.equality_attributes
  end

  # ...

  private

  def equality_attributes
    [name, address]
  end
end