2014-10-07 40 views
0

編寫一個接受任意大小的多維容器並將其轉換爲一維關聯數組的函數,該數組的鍵是表示其值的路徑的字符串原來的容器。任意大小的多維容器並將其轉換爲一維關聯數組

所以{ 'one' => {'two' => 3, 'four' => [ 5,6,7]}, 'eight'=> {'nine'=> {'ten'=>11}}}

將成爲 : "{'one/two' => 3,'one/four/0' => 5, 'one/four/1' => 6, 'one/four/2' => 7, 'eight/nine/ten' : 11}"

到目前爲止,我已經得到了這個...但我有一個很大的問題。任何指向我忽略的東西的指針?

def oneDimHash(hash) 
    if hash.is_a?(Fixnum) 
    puts "AHHH" 
    else 
    hash.each_pair do |key,value| 
     if value.is_a?(Hash) 
     @temp_key << key << '/' 
     oneDimHash(value) 
     elsif value.is_a?(Array) 
     value.each_with_index do |val,index| 
      puts index 
      @temp_key << "#{index}" 
      oneDimHash(val) 
     end 
     else 
     @temp_key << key 
     @result["#{@temp_key}"] = "#{value}" 
     @temp_key = '' 
     end 
    end 
    end 
end 
+1

小心描述一下你想克服的問題嗎? – 2014-10-07 19:55:36

回答

0

立即懷疑您使用實例變量而不是方法參數/局部變量。至少,這很可能就是產生了混亂的密鑰。假設方法簽名不能被修改,你可以通過委託給一個輔助函數來解決對額外參數的需求。也許我會嘗試的方法沿着這些線路:

def oneDimHash(o) 
    oneDimHashInternal("", o, {}) 
end 

def oneDimHashInternal(keyStem, o, hash) 
    if o.is_a? Hash 
    o.each_pair do |key, value| 
     oneDimHashInternal("#{keystem}/#{key}", value, hash) 
    end 
    elsif o.is_a? Array 
    # Work this out for yourself 
    else 
    # Store the (non-container) object in hash 
    # Work this out for yourself 
    end 

    hash 
end 

還要注意有Enumerable S中的沒有使用數組和哈希。我不知道你是否需要考慮這些。

0

這個怎麼樣?

def oneDimHash(obj,parent="") 
    unless obj.is_a?(Hash) 
    puts "AHHH" # or may be better: raise "AHHH" 
    else 
    obj.flat_map do |key,value| 
     combined_key = [parent,key.to_s].join '/' 
     case value 
     when Hash then oneDimHash(value,combined_key).to_a 
     when Array then value.each_with_index.map { |v,i| [combined_key+"/#{i}",v] } 
     else [ [combined_key,value] ] 
     end 
    end.to_h 
    end 
end