我知道如果你有一个array
并将其引用为array.uniq
,它将返回没有任何重复项。
然而在这种情况下,它是一个对象数组(正确的红宝石说话吗?)。我希望每次调用都进入@calls
数组,除非call.from
与数组中已存在的call_formatted对象相同。
如果数组中没有其他对象具有相同的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
答案 0 :(得分:5)
array.uniq { |item| item[:from] }
答案 1 :(得分:1)
使用#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将使该列表唯一。
或者,为了避免在数组中添加所有重复项,您可以使用Hash
构建它:
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,因为它是使用||=
设置的。要使用最后一次出现的call.from,请使用=
的简单分配。
还建议您使用Set
代替Array
。
要采用这种方法,您必须在我们用该字符集填充的类上实施#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">}>
太棒了 - 套装有效!!!
现在,有趣的是,在实施#eql?
和#hash
之后,我们现在可以使用Array#uniq
而无需传入数据块。
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">]
现在,我想知道在开始回答问题之前,StackOverflow是否会因为 太多咖啡 而获奖?
答案 2 :(得分:0)
除非出于某种原因必须是数组,否则我会将数据存储在Hash
中,并以from
值为键。
然后通过from
值查找条目变得简单快捷。您可以选择仅在没有相同键的值时插入新值,或者插入新值并让它用该键替换旧条目。
示例:
calls = Hash.new
def add(call)
if not calls[call.from]
calls[call.from] = call
end
end