在Ruby中使用散列中的键获取特定对象的方便方法? [英] Convenient way of obtaining the specific object being used for a key in a hash in Ruby?

查看:123
本文介绍了在Ruby中使用散列中的键获取特定对象的方便方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有趣的是,我在一个桶分区系统中写了一个场景,我正在写维护索引散列和存储散列的地方,相互关系是UUID生成的,因为这是分布式的,我希望有一些信心,新桶获得独特性在本练习的早期阶段,我开始优化代码以冻结由SecureRandom.uuid生成的所有密钥(它会生成字符串),因为当您使用字符串作为密钥时在散列中会自动被冻结并冻结以确保它不能被更改。 (如果它是一个字符串而不是冻结的)。



在大多数情况下,很容易积极做到这一点,特别是对于新的UUID(实际上在我的项目中,许多这样的值需要这种处理),但在某些情况下,我发现我不得不通过网络传递一个值,然后获得一个哈希值,以确保一致地使用任何以字符串形式存在的字符串,使用相当钝的查找机制。



我的目标是,我希望这可以在多个节点上维护一个庞大的数据集,尽可能地减少密钥和索引存储的开销,并且因为它是一个分区系统,它具有相同的UUID可以多次引用,因此使用相同的引用很有帮助。



这里有一些代码以简单(ish)的形式说明问题。我只是问是否有一个更优化和方便的机制来获得任何具有相同字符串值的键(对于键名而不是关联值)的任何预先存在的对象引用。

 #证明问题.. 

需要'securerandom'

index = Hash.new
store = Hash.new

key ='meh'
value = 1

uuid = SecureRandom.uuid

putsRuby dups和冻结字符串,如果用于哈希键
puts这会产生不同的ID
store [uuid] = value
index [key] = uuid
store.each_key { | X | 存储参考#{x}#{x.object_id}}
index.each_value {| x | puts#{x}#{x.object_id}的索引引用}
puts

puts如果ID出现不一致,那么Ruby会尝试保留冻结键的使用,所以如果它发生在一个区域小心
puts这会产生不同的ID
uuid = uuid.freeze
store [uuid] = value
index [key] = uuid
store.each_key {| x | 存储参考#{x}#{x.object_id}}
index.each_value {| x | 对#{x}#{x.object_id}的索引引用}
puts

puts如果你从一个干净的石板和一个冻结的键开始,你可以克服它,如果你冻结使用前的字符串
puts到目前为止这是干净的并且产生相同的对象
index = Hash.new
store = Hash.new

store [ uuid] = value
index [key] = uuid
store.each_key {| x | 存储参考#{x}#{x.object_id}}
index.each_value {| x | puts#{x}#{x.object_id}的索引引用}
puts

puts但是如果键的值相同(可能是远程),那么它会变得尴尬
puts产生不同的ID
uuid = uuid.dup.freeze
store [uuid] = value
index [key] = uuid
store.each_key {| x | 存储参考#{x}#{x.object_id}}
index.each_value {| x |放入#{x}#{x.object_id}的索引引用}
puts

puts因此,您会遇到这样的怪事,以确保您已经将已经存在的键的标准值存在
puts这清理并产生相同的ID,但是有点尴尬

uuid = uuid.dup.freeze
uuid_list = store.keys
uuid = uuid_list [uuid_list.index(uuid)] if uuid_list.include?(uuid)
store [uuid] = value
index [key] = uuid
store.each_key {| x | 存储参考#{x}#{x.object_id}}
index.each_value {| x | puts#{x}#{x.object_id}的索引引用}
puts

示例运行...

 如果将字符串用于哈希中的键,则Ruby会冻结并冻结字符串
这会生成不同的ID
商店参考价值bd48a581-95e9-452e-b8a3-602d92d47011 70209306325780
bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880

的索引参考如果ID出现不一致,则Ruby尝试保留冻结钥匙的使用,因此如果发生在一个区域,请小心
这会产生不同的ID
bd48a581-95e9-452e-b8a3-602d92d47011的值的存储参考70209306325780
索引参考资料bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880

如果您使用干净的石板和冻结的钥匙开始,您可以在使用前冻结字符串来克服它
这很干净远,并产生相同的对象
商店参考价值bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880
索引参考对于bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880

但是,如果密钥的相同值进入(可能是远程),那么它变得很笨
这会产生不同的ID
存储参考价值bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880
bd48a581-95e9-452e-b8a3-602d92d47011 70209306325000

的索引参考所以,你会遇到这样的怪事,以确保你的标准赋予已存在的键的值
清除并产生相同的ID,但有点尴尬
bd48a581-95e9-452e-b8a3-602d92d47011的商店参考70209306325880
索引参考bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880


解决方案

I在Hash源代码中找不到任何本地内容,而符号不适合我的用途,所以我修改了@ p11y的答案,谢谢^^

  class Hash 

def consistent_key_obj(key)
self.keys.in clude?(关键)? self.find {| K,_ | k == key} .first:key
end

end


Here's an interesting one, I have a scenario in a bucket sharding system I'm writing where I maintain index hashes and storage hashes, the interrelation is a UUID generated because this is distributed and I want some confidence that new buckets gain unique references.

Early on in this exercise I started optimising the code to freeze all keys generated by SecureRandom.uuid (it produces strings) because when you use a string as a key in a hash gets duped and frozen automatically to ensure that it can't be changed. (if it's a String and not frozen).

In most cases it's easy to aggressively do this, particularly for new UUIDs (actually in my project many such values need this treatment) but in some cases I find I'm having to approach a hash with a value passed over the network and obtain then, to ensure consistent use of any strings present as keys, use a rather obtuse lookup mechanism.

My goal in this, since I want this to maintain a huge data set across multiple nodes, to reduce the overhead of key and index storage as much as possible and because it's a bucketing system the same UUID can be referenced many times and as such it's helpful to use the same reference.

Here's some code that demonstrates the issue in a simpl(ish) form. I'm just asking if there's a more optimum and convenient mechanism for obtaining any pre-existing object reference for a key that has the same string value (for the key name and not the value associated).

# Demonstrate the issue..

require 'securerandom'

index = Hash.new
store = Hash.new

key = 'meh'
value = 1

uuid = SecureRandom.uuid

puts "Ruby dups and freezes strings if used for keys in hashes"
puts "This produces different IDs"
store[uuid] = value
index[key] = uuid
store.each_key { |x| puts "Store reference for value of #{x} #{x.object_id}"}
index.each_value { |x| puts "Index reference for #{x} #{x.object_id}" }
puts

puts "If inconsistencies in ID occur then Ruby attempts to preserve the use of the frozen key so if it happens in one area take care"
puts "This produces different IDs"
uuid = uuid.freeze
store[uuid] = value
index[key] = uuid
store.each_key { |x| puts "Store reference for value of #{x} #{x.object_id}"}
index.each_value { |x| puts "Index reference for #{x} #{x.object_id}" }
puts

puts "If you start with a clean slate and a frozen key you can overcome it if you freeze the string before use"
puts "This is clean so far and produces the same object"
index = Hash.new
store = Hash.new

store[uuid] = value
index[key] = uuid
store.each_key { |x| puts "Store reference for value of #{x} #{x.object_id}"}
index.each_value { |x| puts "Index reference for #{x} #{x.object_id}" }
puts

puts "But if the same value for the key comes in (possibly remote) then it becomes awkward"
puts "This produces different IDs"
uuid = uuid.dup.freeze
store[uuid] = value
index[key] = uuid
store.each_key { |x| puts "Store reference for value of #{x} #{x.object_id}"}
index.each_value { |x| puts "Index reference for #{x} #{x.object_id}" }
puts

puts "So you get into oddities like this to ensure you standarise values put in to keys that already exist"
puts "This cleans up and produces same IDs but is a little awkward"

uuid = uuid.dup.freeze
uuid_list = store.keys
uuid = uuid_list[uuid_list.index(uuid)] if uuid_list.include?(uuid)
store[uuid] = value
index[key] = uuid
store.each_key { |x| puts "Store reference for value of #{x} #{x.object_id}"}
index.each_value { |x| puts "Index reference for #{x} #{x.object_id}" }
puts

Example run...

Ruby dups and freezes strings if used for keys in hashes
This produces different IDs
Store reference for value of bd48a581-95e9-452e-b8a3-602d92d47011 70209306325780
Index reference for bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880

If inconsistencies in ID occur then Ruby attempts to preserve the use of the frozen key so if it happens in one area take care
This produces different IDs
Store reference for value of bd48a581-95e9-452e-b8a3-602d92d47011 70209306325780
Index reference for bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880

If you start with a clean slate and a frozen key you can overcome it if you freeze the string before use
This is clean so far and produces the same object
Store reference for value of bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880
Index reference for bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880

But if the same value for the key comes in (possibly remote) then it becomes awkward
This produces different IDs
Store reference for value of bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880
Index reference for bd48a581-95e9-452e-b8a3-602d92d47011 70209306325000

So you get into oddities like this to ensure you standarise values put in to keys that already exist
This cleans up and produces same IDs but is a little awkward
Store reference for value of bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880
Index reference for bd48a581-95e9-452e-b8a3-602d92d47011 70209306325880

解决方案

I couldn't find anything native in the Hash source and Symbols were unsuitable for my purposes so I adapted the answer from @p11y, thanks ^^

class Hash

  def consistent_key_obj(key)
    self.keys.include?(key) ? self.find{|k,_| k == key }.first : key
  end

end

这篇关于在Ruby中使用散列中的键获取特定对象的方便方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆