我有一個結構陣列,我需要根據一個屬性(:num)來保持它們的唯一性。這個陣列將被追加新的結構物件。如果新的結構物件具有重復的 :num 屬性 value,我希望洗掉包含重復的 :num 的舊元素,并將其替換為新元素。
以下是我的意思。讓我們把它設定好:
Gen = Struct.new(:num, :val)
arr = []
arr << Gen.new(11, "foo1"/span>)
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是最新的feed。由于arr已經包含:num 12,我們需要用新的結構來替換它。由于 s2 包含一個唯一的 :num,它應該能夠被追加,沒有問題(即使 s2 包含一個重復的 :val,這應該沒有關系,我只關心如何保持 :num 的唯一性)。
最后,我需要arr看起來像:
[#<struct num=11, val="foo1">, #<struct num=12, val="foo10"> , #<struct num=13, val="foo3"> ]
陣列的順序并不重要。
我已經看過在陣列中添加元素(如果它不在那里),在陣列中插入唯一專案的Ruby條件,從Ruby中洗掉重復元素 ,以及其他一些帖子。他們都是在處理簡單的陣列,而不是結構的陣列。
我怎樣才能做到這一點呢?
uj5u.com熱心網友回復:
最簡單的做法是維護一個哈希值,其鍵值為:num的值,其值為相關的結構。該哈希值(h)可以用一個新的結構(st)按所需的方式進行更新,如下所示。
def add_struct(h, st)
h.update(st[:num]=>st)
end>
當需要一個當前結構的陣列時,只需回傳哈希的值即可。
參見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 })的簡寫。add_struct的回傳值是h的更新值。
這里有一個例子。
Gen = Struct.new(:num, :val)
s1 = Gen.new(11, "foo1")
#=> #<struct Gen num=11, val="foo1" >
s2 = Gen.new(12, "foo2"/span>)
#=> #<struct Gen num=12, val="foo2">/span>
s3 = Gen.new(12, "foo10")
#=> #<struct Gen num=12, val="foo10">/span>
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.值
#=> [#<struct Gen num=11, val="foo1">, h.value
#<struct Gen num=12, val="foo10">,
# #<struct Gen num=13, val="foo3" >]
uj5u.com熱心網友回復:
將新的gens逐個進行。找到相應的舊基因,讓它擁有新基因的價值。如果沒有找到舊的基因,則添加完整的新基因。
Gen = Struct.new(:num, :val)
arr = []
arr << Gen.new(11, "foo1"/span>)
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">] /span>
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/306934.html
標籤:
