操作Ruby哈希表

3
使用Ruby,我需要将这个转换...
{"30"=>["Morgan", ["lib1", "lib2"]], 
 "31"=>["Morgan", ["lib9", "lib2", "lib3"]], 
 "32"=>["Gary", ["lib1", "lib2"]], 
 "33"=>["Morgan", ["lib1"]], 
 "34"=>["Morgan", []], 
 "35"=>["Morgan", []], 
 "36"=>["Morgan", ["lib3", "lib2"]], 
 "37"=>["jim", ["lib1"]]}

转化为这样...
{"Morgan"=>[30,31,33,34,35,36], 
 "Gary"=>[32], []=>[34,35], 
 "jim"=>[37]}

有什么想法吗?

3
定义转换规则。 - Sergio Tulentsev
1
我同意@SergioTulentsev的观点,不太清楚如何从输入哈希获取输出哈希 - 大多数情况下为什么[]成为结果的一部分,但是["lib1"]等却没有? - Andrew Marshall
转换规则很奇怪,但是可以实现,看看我的答案。 - megas
1
@megas 是的,但仅仅因为一个问题的单个示例有效,并不意味着在这个问题中我们没有遗漏一些非显而易见的规则。而且这个问题很奇怪,需要澄清。 - Andrew Marshall
一行代码:my_hash.reduce({}){|h,(k,(v,*o))| (h[v] ||= []) << k;h} - ShadyKiller
4个回答

2
input.each_with_object(Hash.new{|h,k|h[k]=[]}) do |(k,v),res|
  (v.last.empty? ? res[[]] : res[v.first]) << k.to_i
end

=> {"Morgan"=>[30, 31, 33, 36], "Gary"=>[32], []=>[34, 35], "jim"=>[37]}

0
newhash={}    
hash.inver­t.each {|k,v­| newha­sh[k.first­].concat [v] }

invert 方法在你想做的事情中非常有用。但我不明白这些值中的 "lib" 部分与转换有什么关系,请澄清一下。


如果两个键具有相同的值,则此方法无法正常工作,因为“invert”不会将它们合并,而是覆盖其中一个。 - Andrew Marshall
哦,我以为这很容易。坏消息。 - ichigolas

0
def convert(input)          
    output = {}                     
    noLibKey = []                   
    input.each do |key, value|      
            number = key.to_i               
            name = value[0]                 
            libs = value[1]                 
            if libs.empty?                  
                    output[noLibKey] ||= []         
                    output[noLibKey] << number      
            end                             
            output[name] ||= []             
            output[name] << number          
    end                             
    return output                   
end

0
A = {"30"=>["Morgan", ["lib1", "lib2"]], 
 "31"=>["Morgan", ["lib9", "lib2", "lib3"]], 
 "32"=>["Gary", ["lib1", "lib2"]], 
 "33"=>["Morgan", ["lib1"]], 
 "34"=>["Morgan", []], 
 "35"=>["Morgan", []], 
 "36"=>["Morgan", ["lib3", "lib2"]], 
 "37"=>["jim", ["lib1"]]}

B = Hash.new;
A.each do |k,i|
    if !B[i[0]].kind_of?(Array)
        B[i[0]] = Array.new;
    end
    B[i[0]]<<k
    puts "#{k} #{i[0]}"

end

B.each do |k,i|
    puts "#{k} #{i}"
end

作为一个示例代码 :)


啊,但是 B[i[0]] ||= []if!...kind_of? ... = Array.new 好看多了! - Andrew Marshall
我不是专家,只是提供一些意见... - erogol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接