我有以下哈希:
new_hash = {
[1] => [2, 3, 4, 7, 8 ],
[2] => [3, 5],
[3] => [5, 6, 7, 8, 9, 10],
[4] => [],
}
我想选择具有最多元素的密钥,即第三个密钥。
我试过了:
selected_user = new_hash.max_by{|k,v| v.length}.first
找到包含最多元素的键后,我想删除所有其他元素的值。我想要的结果是:
new_hash = {
[1] => [2, 3, 4],
[2] => [3],
[3] => [5, 6, 7, 8, 9, 10],
[4] => [],
}
我尝试使用数组删除所有重复的项目,方法是将值推入数组,然后删除2D数组中的所有元素。
for a in 0..new_arr.length-1
new_arr[a] = new_arr[a] - newer_arr
end
这是可行的,但是大散列的速度非常低。如何提高此操作的速度?
答案 0 :(得分:1)
new_hash = { [1] => [2, 3, 4, 7, 8 ], [2] => [3, 5], [3] => [5, 6, 7, 8, 9, 10], [4] => [], }
selected_user = new_hash.max_by{|k,v| v.length}.first
selected_values = new_hash[selected_user]
new_hash.each do |k, v|
next if k == selected_user
new_hash[k] = v - selected_values
end
puts new_hash
运行时:
{[1]=>[2, 3, 4], [2]=>[3], [3]=>[5, 6, 7, 8, 9, 10], [4]=>[]}
答案 1 :(得分:0)
这样做:
selected_user_key = new_hash.max_by{|k,v| v.length}.first
# I suggest to use dup to not alter the original new_hash
return_hash = new_hash.dup
# Step 1 - remove the element from the hash
elements_of_selected_user = return_hash.delete(selected_user_key)
# Step 2 - remove the items that are in elements_of_selected_user
return_hash = Hash[return_hash.map{|k,v| [k, v - elements_of_selected_user]}]
# Step 3 - add the element back to the hash
return_hash[selected_user_key] = elements_of_selected_user
这是有效的,因为在Ruby中你可以执行诸如-
之类的数组操作:
[1,2,3] - [2] == [1, 3]
答案 2 :(得分:0)
一种方式:
key, value = new_hash.max_by { |_,a| a.size }
new_hash.merge(new_hash) { |_,v| v - value }.update(key=>value)
#=> {[1]=>[2, 3, 4], [2]=>[3], [3]=>[5, 6, 7, 8, 9, 10], [4]=>[]}
这使用采用块
的Hash#merge形式{ |_,v| v - value }
确定合并散列中每个键的值。
如果两个键的数组大小与其值相同,则结果当然取决于键的顺序(Ruby v1.9 +)。
答案 3 :(得分:0)
很可能它是阵列而不是哈希会减慢你的速度......
使用[1,2,3] - [1,2]
时,您正在创建第三个数组,并且在迭代Hash时创建越来越多的对象会调用内存分配,这会降低您的速度。
如果您知道数组的所有成员都是唯一的,我建议您使用集合代替数组,利用Set#subtract方法......
require 'set'
new_hash = {
[1] => [2, 3, 4, 7, 8 ].to_set,
[2] => [3, 5].to_set,
[3] => [5, 6, 7, 8, 9, 10].to_set,
[4] => [].to_set,
}
selected_user = new_hash.max_by{|k,v| v.length}.first
values = new_hash[selected_user]
new_hash.each {|k, v| v.subtract values unless k == selected_user}
由于内存分配和对象管理的不同,Set对象的创建速度稍慢,但由于您不是使用此过程创建新对象,因此它应该稍微高效 - 特别是对于大型持久性数据结构。
P.S。
您是否有理由在用户ID密钥中使用Arrays?散列键是冻结的,无法更改,因此我没有看到使用数组的附加值(与FixNum相比,这会降低你的速度。)
为什么不使用:
require 'set'
new_hash = {
1 => [2, 3, 4, 7, 8 ].to_set,
2 => [3, 5].to_set,
3 => [5, 6, 7, 8, 9, 10].to_set,
4 => [].to_set,
}