Ruby 更快地删除数组散列中的值
我有以下散列:Ruby 更快地删除数组散列中的值,ruby,hash,Ruby,Hash,我有以下散列: 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
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
这是可行的,但是大型散列的速度非常低。如何提高此操作的速度
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]=>[]}
这样做:
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]
单向:
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]=>[]}
这使用了使用块的形式
{ |_,v| v - value }
确定合并哈希中每个键的值
如果两个键的数组大小与其值相同,那么结果当然取决于键的顺序(Ruby v1.9+) 很有可能是数组而不是散列让你慢下来了 当您使用
[1,2,3]-[1,2]
时,您正在创建第三个数组,并且当您迭代散列时,创建越来越多的对象会调用内存分配,这会降低您的速度
如果您知道数组的所有成员都是唯一的,我建议您使用集合而不是数组,利用该方法
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对象的创建稍微慢一些,但是由于您没有使用此过程创建新对象,因此它应该稍微高效一些,特别是对于大型持久数据结构
附言
在用户id密钥中使用数组有什么原因吗?散列键是冻结的,无法更改,因此我看不到使用数组的附加值(与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,
}