ruby रूबे में CamelCase से snake_case करने के लिए नेस्टेड हैश कुंजी कनवर्ट करना




hash key (4)

मैं एक एपीआई रैपर मणि बनाने की कोशिश कर रहा हूं, और जेएसओएन एपीआई रिटर्न से अधिक रूबीश प्रारूप में हैश कुंजी को कनवर्ट करने के साथ समस्याएं हैं।

जेएसओएन में हैश और एरे दोनों, घोंसले की कई परतें हैं। मैं क्या करना चाहता हूं कि आसान उपयोग के लिए सभी कुंजी को snake_case में दोबारा परिवर्तित करना है।

यहां तक ​​कि मुझे अब तक क्या मिला है:

def convert_hash_keys(value)
  return value if (not value.is_a?(Array) and not value.is_a?(Hash))
  result = value.inject({}) do |new, (key, value)|
    new[to_snake_case(key.to_s).to_sym] = convert_hash_keys(value)
    new
  end
  result
end

उपरोक्त स्ट्रिंग को snake_case में बदलने के लिए इस विधि को कॉल करता है:

def to_snake_case(string)
  string.gsub(/::/, '/').
  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
  gsub(/([a-z\d])([A-Z])/,'\1_\2').
  tr("-", "_").
  downcase
end

आदर्श रूप में, परिणाम निम्न के जैसा होगा:

hash = {:HashKey => {:NestedHashKey => [{:Key => "value"}]}}

convert_hash_keys(hash)
# => {:hash_key => {:nested_hash_key => [{:key => "value"}]}}

मुझे रिकर्सन गलत मिल रहा है, और इस तरह के समाधान के हर संस्करण में मैंने कोशिश की है या तो पहले स्तर से प्रतीकों को परिवर्तित नहीं करता है, या ओवरबोर्ड चला जाता है और मूल्य सहित पूरे हैश को बदलने की कोशिश करता है।

यदि संभव हो तो वास्तविक हैश और स्ट्रिंग फ़ंक्शंस को संशोधित करने के बजाय, इसे एक सहायक वर्ग में हल करने का प्रयास करें।

पहले ही, आपका बहुत धन्यवाद।


यदि आप रेल का उपयोग करते हैं:

हैश के साथ उदाहरण: snel_case के लिए camelCase :

hash = { camelCase: 'value1', changeMe: 'value2' }

hash.transform_keys { |key| key.to_s.underscore }
# => { "camel_case" => "value1", "change_me" => "value2" }

स्रोत: http://apidock.com/rails/v4.0.2/Hash/transform_keys

नेस्टेड विशेषताओं के लिए transform_keys के बजाय deep_transform_keys का उपयोग करें, उदाहरण:

hash = { camelCase: 'value1', changeMe: { hereToo: { andMe: 'thanks' } } }

hash.deep_transform_keys { |key| key.to_s.underscore }
# => {"camel_case"=>"value1", "change_me"=>{"here_too"=>{"and_me"=>"thanks"}}}

स्रोत: http://apidock.com/rails/v4.2.7/Hash/deep_transform_keys


आपको अलग-अलग ऐरे और हैश का इलाज करने की आवश्यकता है। और, यदि आप रेल में हैं, तो आप अपने to_snake_case बजाय underscore उपयोग कर सकते हैं। शोर को कम करने के लिए पहले थोड़ा सा सहायक:

def underscore_key(k)
  k.to_s.underscore.to_sym
  # Or, if you're not in Rails:
  # to_snake_case(k.to_s).to_sym
end

यदि आपके हैश में ऐसी कुंजी होंगी जो सिंबल या स्ट्रिंग्स नहीं हैं तो आप underscore_key उचित रूप से संशोधित कर सकते हैं।

यदि आपके पास ऐरे है, तो आप केवल ऐरे के प्रत्येक तत्व में convert_hash_keys को पुन: रूप से लागू करना चाहते हैं; यदि आपके पास हैश है, तो आप underscore_key साथ चाबियाँ ठीक करना चाहते हैं और प्रत्येक मूल्य में convert_hash_keys लागू करें; यदि आपके पास कुछ और है तो आप इसे बिना छेड़छाड़ से गुजरना चाहते हैं:

def convert_hash_keys(value)
  case value
    when Array
      value.map { |v| convert_hash_keys(v) }
      # or `value.map(&method(:convert_hash_keys))`
    when Hash
      Hash[value.map { |k, v| [underscore_key(k), convert_hash_keys(v)] }]
    else
      value
   end
end

'एमयू बहुत छोटा है' द्वारा स्वीकृत उत्तर को एक मणि, भविष्य में चिंराट के प्लिसकेन में परिवर्तित कर दिया गया है:

https://github.com/futurechimp/plissken/blob/master/lib/plissken/ext/hash/to_snake_keys.rb

ऐसा लगता है कि इसे रेल के बाहर काम करना चाहिए क्योंकि अंडरस्कोर कार्यक्षमता शामिल है।


यदि आप active_support लाइब्रेरी का उपयोग कर रहे हैं, तो आप deep_transform_keys का उपयोग कर सकते हैं! इस तरह:

hash.deep_transform_keys! do |key|
  k = key.to_s.snakecase rescue key
  k.to_sym rescue key
end






hash-of-hashes