ruby – 在迭代Hash / Array时区分{k :: v}与[:k,:v]
发布时间:2020-12-17 02:08:08 所属栏目:百科 来源:网络整理
导读:我需要在#each上实现回调.每个接收器可能都是Array和Hash.所以,我有一个代码: receiver.each do |k,v| case receiver when Hash then puts "#{k} = #{v}" when Array then puts "[#{k},#{v}]" endend 但接收器的检查是蹩脚的.有没有办法接收/解释一个代码块
我需要在#each上实现回调.每个接收器可能都是Array和Hash.所以,我有一个代码:
receiver.each do |k,v| case receiver when Hash then puts "#{k} = #{v}" when Array then puts "[#{k},#{v}]" end end 但接收器的检查是蹩脚的.有没有办法接收/解释一个代码块参数[s],以清楚地区分以下情况: { a: 1,b: 2 } 与 [[:a,1],[:b,2]] 我尝试过括号,单个参数,splatted参数.一切都只是得到一个大小为2的数组.我注定要坚持显式类型检查? 解决方法
您可以做的最好的事情是从循环中获取类型检查:
def foo(receiver) format = receiver.is_a?(Array) ? "[%s,%s]" : "%s = %s" receiver.each do |k_v| puts format % k_v end end >见String#% 如果你想在每个块中告诉键/值对是来自数组还是哈希,你必须求助于猴子修补.它可以做到,但它非常糟糕: class Hash orig_each = instance_method(:each) define_method(:each) do |&block| orig_each.bind(self).call do |kv| def kv.from_hash? true end def kv.from_array? false end block.call(kv) end end end class Array orig_each = instance_method(:each) define_method(:each) do |&block| orig_each.bind(self).call do |kv| def kv.from_hash? false end def kv.from_array? true end block.call(kv) end end end 正在使用: e = {a: 1,b: 2} e.each do |kv| p [kv.from_hash?,kv.from_array?,kv] end # => [true,false,[:a,1]] # => [true,2]] e = [[:a,2]] e.each do |kv| p [kv.from_hash?,kv] end # => [false,true,1]] # => [false,2]] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |