Ruby on rails 将唯一项插入数组的Ruby条件

Ruby on rails 将唯一项插入数组的Ruby条件,ruby-on-rails,ruby,Ruby On Rails,Ruby,我知道,如果您有一个数组,并将其引用为数组。uniq它将返回而不带任何重复项 然而,在本例中,它是一个对象数组(这是正确的ruby语言吗?)。我希望每个调用都进入@calls数组,除非调用.from与数组中已存在的调用格式的对象相同 如果数组中没有其他对象具有相同的call.from值,如何有条件地将这些对象放置在数组中 calls_raw.each do |call| call_formatted = { :date => dat

我知道,如果您有一个
数组
,并将其引用为
数组。uniq
它将返回而不带任何重复项

然而,在本例中,它是一个对象数组(这是正确的ruby语言吗?)。我希望每个调用都进入
@calls
数组,除非
调用.from
与数组中已存在的调用格式的对象相同

如果数组中没有其他对象具有相同的
call.from
值,如何有条件地将这些对象放置在数组中

calls_raw.each do |call|       
        call_formatted = {
              :date => date,
              :time => time,
              :from => call.from,
              :duration => call.duration,
              :recording => recording,
        }
        @calls << call_formatted
end
calls_raw.each do|call|
调用\u格式={
:date=>date,
:time=>time,
:from=>call.from,
:duration=>call.duration,
:录制=>录制,
}
@调用使用
#map
为您构建阵列,并在其上调用
#uniq

calls_raw.map do |call|       
        {
              :date => date,
              :time => time,
              :from => call.from,
              :duration => call.duration,
              :recording => recording,
        }
end.uniq{|call| call[:from]}
上述方法将首先构建一个大于最终需要的调用数组,最后对#uniq的调用将使列表唯一

或者,为了避免在数组中添加所有重复项,您可以使用
散列来构建它,如下所示:

calls_raw.each_with_object do |call, h|       
        h[call.from] ||= {
              :date => date,
              :time => time,
              :from => call.from,
              :duration => call.duration,
              :recording => recording,
        }
end.values
Hash
方法将使用call.from的第一个匹配项,因为它是用
|124;=
设置的。使用调用的最后一次出现。然后使用带有
=
的简单赋值

还有人建议只使用
集合
而不是
数组

要采用这种方法,您必须在我们填充集合的类上实现
#eql?
#hash

class CallRaw
  attr_accessor :from

  def initialize(from)
    self.from = from
  end

  def eql?(o)
    # Base equality on 'from'
    o.from == self.from
  end

  def hash 
    # Use the hash of 'from' for our hash
    self.from.hash
  end
end

require 'set'
s = Set.new
 => <Set: {}>

s << CallRaw.new("Chewbaca")
 => <Set: {<CallRaw:0x00000002211888 @from="Chewbaca">}> 

# We expect now, that adding another will not grow our set any larger
s << CallRaw.new("Chewbaca")
 => <Set: {<CallRaw:0x00000002211888 @from="Chewbaca">}> 

# Great, it's not getting any bigger
s << CallRaw.new("Chewbaca")
s << CallRaw.new("Chewbaca")
 => <Set: {#<CallRaw:0x00000002211888 @from="Chewbaca">}> 

现在,我只是想知道是否有一个徽章会因为回答问题之前喝了太多的咖啡而获奖?

除非有某种原因,否则它必须是一个数组,否则我会将数据存储在一个
散列中,由
from
值键入

然后,通过
from
值可以轻松快速地查找条目。您可以选择仅在没有具有相同键的值时插入新值,或者插入新值并让它用该键替换旧条目

例如:

calls = Hash.new

def add(call)
  if not calls[call.from]
    calls[call.from] = call
  end
end

如果你使用一个集合,它不会简化事情吗?请参阅@panmari,您不是指散列,键是
call.from
的值?如果不是的话,那在一套设备上是如何工作的呢?
a = Array.new

a << CallRaw.new("Chewbaca")
 => [<CallRaw:0x000000021e2128 @from="Chewbaca">] 

a << CallRaw.new("Chewbaca")
 => [<CallRaw:0x000000021e2128 @from="Chewbaca">, <CallRaw:0x000000021c2bc0 @from="Chewbaca">]

a.uniq
 => [<CallRaw:0x000000021e2128 @from="Chewbaca">]
calls = Hash.new

def add(call)
  if not calls[call.from]
    calls[call.from] = call
  end
end