我正在创建一个数组中的哈希列表,如果它们是相同的,我们会保留一个计数。
以下是示例哈希的样子:
data = {
s: y.id,
t: z.id,
count: 0
}
我正在迭代一堆这些哈希并将它们推送到列表中。我希望这样,当s
和t
的值已经存在于列表中的哈希中时,count
将会增加。
让我澄清一下。假设这是我的@list
@list = [
{
s: 1,
t: 2,
count: 5
},
{
s: 1,
t: 3,
count: 5
}
]
现在假设,我想将以下哈希值推送到列表中:
data = {
s: 1,
t: 2,
count: 0
}
@list的结果应如下所示:因为列表中已存在s==1
和t==2
的哈希:
@list = [
{
s: 1,
t: 2,
count: 6
},
{
s: 1,
t: 3,
count: 5
}
这是我目前所处的位置。
@final = []
while widgets.count > 1
widget = widgets.shift
widgets.each do |w|
data = {
s: widget.id,
t: w.id,
count: 0
}
@final << data
end
end
这只会将所有排列添加到列表中,但我希望在s
和t
相同且只是增加count
时阻止重复。
我希望我很清楚。
任何建议都将不胜感激。
答案 0 :(得分:1)
如果我的问题是正确的,你可以使用list中的find方法传递一个块,你可以在其中指定你想要匹配的条件(s和t的值已经存在于@final列表中)。
这是我直接使用列表和哈希的示例。
widgets = [{s:1, t:2, count:0}, {s: 1, t:2, count:0}, {s: 1, t:2, count:0},
{s:1, t:3, count:0}, {s:1, t:3, count:0}]
@final = []
widgets.each do |widget|
res = @final.find {|obj| obj[:s] == widget[:s] && obj[:t] == widget[:t] }
if res.nil?
widget[:count] = 1
@final << widget
else
res[:count] += 1
end
end
puts @final.inspect
此代码的答案是
[{:s=>1, :t=>2, :count=>3}, {:s=>1, :t=>3, :count=>2}]
按预期
答案 1 :(得分:1)
我会这样做(假设我正确理解了这个问题):
def add_hash(data)
h, i = @list.each_with_index.find {|h,i| data[:s]==h[:s] && data[:t]==h[:t]}
if h
@list[i][:count] += 1
else
data[:count] = 1
@list << data
end
end
add_hash( { s: 1, t: 3, count: 0 } )
@list # @list => [{:s=>1, :t=>2, :count=>5}, {:s=>1, :t=>3, :count=>6}]
add_hash( { s: 2, t: 3, count: 0 } )
@list # @list # => [{:s=>1, :t=>2, :count=>5}, {:s=>1, :t=>3, :count=>5},
{:s=>2, :t=>3, :count=>1}]
如果您可以更改@list
,请考虑将其设为哈希:
@hash = { { s: 1, t: 2 } => 5, { s: 1, t: 3 } => 5 }
答案 2 :(得分:0)
不确定我是否正确解答了您的问题,但是如果您希望count
中每个data
哈希中的data.s == data.t
属性增加,那么这应该可以解决问题:
@final = []
while widgets.count > 1
widget = widgets.shift
widgets.each do |w|
data = {
s: widget.id,
t: w.id,
count: 0
}
if data.s == data.t
data.count += 1
end
@final << data
end
end
答案 3 :(得分:0)
def reduce_matches(collection)
result.reduce([]) do |arr, element|
matching(arr, element) ? matching[:count] += 1 : arr << element
arr
end
end
def matching(coll, candidate)
coll.detect do |element|
element[:s] == candidate[:s] && element[:t] == candidate[:t]
end
end
现在您可以输入:
reduce_matches(widgets)
它可以满足您的需求。例如,如果
widgets = [
{
s: 1,
t: 2,
count: 0
},
{
s: 2,
t: 3,
count: 0
},
{
s: 1,
t: 2,
count: 0
},
]
然后
reduce_matches(widgets) = [
{
s: 1,
t: 2,
count: 1
},
{
s: 2,
t: 3,
count: 0
}
]
想要向窗口小部件添加新元素吗?
widgets << new_element
reduce_matches(widgets)