如何根据属性附加一个唯一的结构数组?
How to append a unique array of struct based on an attribute?
我有一个结构数组,我需要根据属性使它们保持唯一,:num
。该数组将附加新的结构对象。如果新结构对象有一个重复的:num
属性值,我想删除包含重复:num
的旧元素并用新元素替换它。
这就是我的意思。让我们设置它:
Gen = Struct.new(:num, :val)
arr = []
arr << Gen.new(11, "foo1")
arr << Gen.new(12, "foo2")
# [#<struct num=11, val="foo1">, #<struct num=12, val="foo2">]
然后我用新的结构喂它。让我们构建它们:
s1 = Gen.new(12, "foo10")
s2 = Gen.new(13, "foo3")
- 如果我这样做
arr << s1
,它只会将 s1
附加到 arr
。
- 如果我在执行上述操作后执行
arr.uniq {|el| el.number}
,它有时会删除“foo10”,但我想始终保留最新的结构。
当 s1
附加到 arr
时,它需要替换旧的 #<struct num=12, val="foo2">
结构,因为 s1
是最新的提要。由于 arr
已经包含 :num
12,我们需要用新结构替换它。由于 s2
包含一个唯一的 :num
,它应该能够被追加没问题(即使 s2
包含一个重复的 :val
,也没关系,我只是担心保持 :num
独特)。
最后,我需要arr
看起来像:
[#<struct num=11, val="foo1">, #<struct num=12, val="foo10">, #<struct num=13, val="foo3">]
数组的顺序无关紧要。
我查看了 Add element to an array if it's not there already, 、从 Ruby 中的数组中删除重复元素
,以及其他一些帖子。它们主要处理简单数组,而不是结构数组。
我怎样才能做到这一点?
把新的 gen
一个接一个。找到对应的old gen,让它拥有new one的值。如果没有找到老一代,添加完整的新一代。
Gen = Struct.new(:num, :val)
arr = []
arr << Gen.new(11, "foo1")
arr << Gen.new(12, "foo2")
new_gens = [Gen.new(12, "foo10"),
Gen.new(13, "foo3")]
#let's go
new_gens.each do |new_gen|
match = arr.detect{|old_gen| old_gen.num == new_gen.num}
match ? match.val = new_gen.val : arr << new_gen
end
p arr # =>[#<struct num=11, val="foo1">, #<struct num=12, val="foo10">, #<struct num=13, val="foo3">]
维护一个散列是最简单的,其键是 :num
的值,其值是关联的结构。哈希 (h
) 可以按如下所需方式使用新结构 (st
) 进行更新。
def add_struct(h, st)
h.update(st[:num]=>st)
end
然后当需要当前结构数组时,只需 return 散列值。
参见 Hash#update(又名 merge!
)。回想一下,如果哈希 h
和 g
都有一个键 k
,则哈希 h.update(g)
(或 h.merge(g)
)中 k
的值等于g[k]
。对于 h.update({ st[:num]=>st })
,h.update(st[:num]=>st)
是 shorthand。 add_struct
的return值是h
的更新值。
这是一个例子。
Gen = Struct.new(:num, :val)
s1 = Gen.new(11, "foo1")
#=> #<struct Gen num=11, val="foo1">
s2 = Gen.new(12, "foo2")
#=> #<struct Gen num=12, val="foo2">
s3 = Gen.new(12, "foo10")
#=> #<struct Gen num=12, val="foo10">
s4 = Gen.new(13, "foo3")
#=> #<struct Gen num=13, val="foo3">
h = {}
add_struct(h, s1)
#=> {11=>#<struct Gen num=11, val="foo1">}
add_struct(h, s2)
#=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo2">}
add_struct(h, s3)
#=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo10">}
add_struct(h, s4)
#=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo10">,
# 13=>#<struct Gen num=13, val="foo3">}
h #=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo10">,
# 13=>#<struct Gen num=13, val="foo3">}
h.values
#=> [#<struct Gen num=11, val="foo1">,
# #<struct Gen num=12, val="foo10">,
# #<struct Gen num=13, val="foo3">]
我有一个结构数组,我需要根据属性使它们保持唯一,:num
。该数组将附加新的结构对象。如果新结构对象有一个重复的:num
属性值,我想删除包含重复:num
的旧元素并用新元素替换它。
这就是我的意思。让我们设置它:
Gen = Struct.new(:num, :val)
arr = []
arr << Gen.new(11, "foo1")
arr << Gen.new(12, "foo2")
# [#<struct num=11, val="foo1">, #<struct num=12, val="foo2">]
然后我用新的结构喂它。让我们构建它们:
s1 = Gen.new(12, "foo10")
s2 = Gen.new(13, "foo3")
- 如果我这样做
arr << s1
,它只会将s1
附加到arr
。 - 如果我在执行上述操作后执行
arr.uniq {|el| el.number}
,它有时会删除“foo10”,但我想始终保留最新的结构。
当 s1
附加到 arr
时,它需要替换旧的 #<struct num=12, val="foo2">
结构,因为 s1
是最新的提要。由于 arr
已经包含 :num
12,我们需要用新结构替换它。由于 s2
包含一个唯一的 :num
,它应该能够被追加没问题(即使 s2
包含一个重复的 :val
,也没关系,我只是担心保持 :num
独特)。
最后,我需要arr
看起来像:
[#<struct num=11, val="foo1">, #<struct num=12, val="foo10">, #<struct num=13, val="foo3">]
数组的顺序无关紧要。
我查看了 Add element to an array if it's not there already,
我怎样才能做到这一点?
把新的 gen
一个接一个。找到对应的old gen,让它拥有new one的值。如果没有找到老一代,添加完整的新一代。
Gen = Struct.new(:num, :val)
arr = []
arr << Gen.new(11, "foo1")
arr << Gen.new(12, "foo2")
new_gens = [Gen.new(12, "foo10"),
Gen.new(13, "foo3")]
#let's go
new_gens.each do |new_gen|
match = arr.detect{|old_gen| old_gen.num == new_gen.num}
match ? match.val = new_gen.val : arr << new_gen
end
p arr # =>[#<struct num=11, val="foo1">, #<struct num=12, val="foo10">, #<struct num=13, val="foo3">]
维护一个散列是最简单的,其键是 :num
的值,其值是关联的结构。哈希 (h
) 可以按如下所需方式使用新结构 (st
) 进行更新。
def add_struct(h, st)
h.update(st[:num]=>st)
end
然后当需要当前结构数组时,只需 return 散列值。
参见 Hash#update(又名 merge!
)。回想一下,如果哈希 h
和 g
都有一个键 k
,则哈希 h.update(g)
(或 h.merge(g)
)中 k
的值等于g[k]
。对于 h.update({ st[:num]=>st })
,h.update(st[:num]=>st)
是 shorthand。 add_struct
的return值是h
的更新值。
这是一个例子。
Gen = Struct.new(:num, :val)
s1 = Gen.new(11, "foo1")
#=> #<struct Gen num=11, val="foo1">
s2 = Gen.new(12, "foo2")
#=> #<struct Gen num=12, val="foo2">
s3 = Gen.new(12, "foo10")
#=> #<struct Gen num=12, val="foo10">
s4 = Gen.new(13, "foo3")
#=> #<struct Gen num=13, val="foo3">
h = {}
add_struct(h, s1)
#=> {11=>#<struct Gen num=11, val="foo1">}
add_struct(h, s2)
#=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo2">}
add_struct(h, s3)
#=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo10">}
add_struct(h, s4)
#=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo10">,
# 13=>#<struct Gen num=13, val="foo3">}
h #=> {11=>#<struct Gen num=11, val="foo1">,
# 12=>#<struct Gen num=12, val="foo10">,
# 13=>#<struct Gen num=13, val="foo3">}
h.values
#=> [#<struct Gen num=11, val="foo1">,
# #<struct Gen num=12, val="foo10">,
# #<struct Gen num=13, val="foo3">]