প্রতীক সহ রুবি হ্যাশে কোনও জসন ফর্ম্যাট কী কী জুটি রূপান্তর করার সর্বোত্তম উপায় কী?


102

আমি ভাবছি যে একটি জসন ফর্ম্যাট কী কী জোড়াকে কী হিসাবে প্রতীক সহ রুবি হ্যাশে রূপান্তর করার সর্বোত্তম উপায়: উদাহরণ:

{ 'user': { 'name': 'foo', 'age': 40, 'location': { 'city' : 'bar', 'state': 'ca' } } }
==> 
{ :user=>{ :name => 'foo', :age =>'40', :location=>{ :city => 'bar', :state=>'ca' } } }

কোন সাহায্যকারী পদ্ধতি এটি করতে পারে?


http://stackoverflow.com/a/43773159/12974354.1 রেলের জন্য এটি ব্যবহার করে দেখুন
Rails_id

উত্তর:


255

json স্ট্রিংকে পার্স করার সময় json রত্ন ব্যবহার করে আপনি প্রতীকী_নাম বিকল্পে পাস করতে পারেন। এখানে দেখুন: http://flori.github.com/json/doc/index.html (পার্সের নীচে দেখুন)

উদাহরণ:

>> s ="{\"akey\":\"one\",\"bkey\":\"two\"}"
>> JSON.parse(s,:symbolize_names => true)
=> {:akey=>"one", :bkey=>"two"} 

4
রুবি 1.9 উপায় দ্বারা এই লাইব্রেরি অন্তর্ভুক্ত।
সাইমন পেরেলপিলিটসা

এটা কি আগে করতেন না :symbolize_keys? কেন নাম বদলে গেল?
লুকাস

5
@ লুকাস: symbolize_keysএটি একটি রেলের জিনিস।
ওয়াইটিসিমো

: প্রতীকী
নামগুলি

19

লেভেনটিক্স, আপনার উত্তরের জন্য আপনাকে ধন্যবাদ।

Marshal.load (Marshal.dump (জ)) কারণ এটি মূল চাবি ধরনের অপরিবর্তিত পদ্ধতি সম্ভবত বিভিন্ন পদ্ধতি অধিকাংশ অখণ্ডতা হয়েছে যাও recursively

স্ট্রিং এবং সিম্বল কীগুলির মিশ্রণের সাথে আপনার নেস্টেড হ্যাশ রয়েছে এবং আপনি সেই মিশ্রণটি ডিকোডের উপরে সংরক্ষণ করতে চান (উদাহরণস্বরূপ, যদি আপনার হ্যাশটিতে অত্যন্ত জটিল / নেস্টেড তৃতীয় ছাড়াও আপনার নিজস্ব কাস্টম অবজেক্ট থাকে তবে এটি ঘটতে পারে পার্টির অবজেক্টস যার কীগুলি আপনি কোনও প্রকল্পের সময়সীমাবদ্ধতার মতো যেকোন কারণেই হেরফের / রূপান্তর করতে পারবেন না)।

উদাহরণ:

h = {
      :youtube => {
                    :search   => 'daffy',                 # nested symbol key
                    'history' => ['goofy', 'mickey']      # nested string key
                  }
    }

পদ্ধতি 1 : JSON.parse - সমস্ত কী পুনরাবৃত্তভাবে প্রতীকী => মূল মিশ্রণ সংরক্ষণ করে না

JSON.parse( h.to_json, {:symbolize_names => true} )
  => { :youtube => { :search=> "daffy", :history => ["goofy", "mickey"] } } 

পদ্ধতি 2 : অ্যাক্টিভসপোর্ট :: জেএসএন.ডেকোড - কেবলমাত্র শীর্ষ স্তরের কীগুলি প্রতীকী>> মূল মিশ্রণ সংরক্ষণ করে না

ActiveSupport::JSON.decode( ActiveSupport::JSON.encode(h) ).symbolize_keys
  => { :youtube => { "search" => "daffy", "history" => ["goofy", "mickey"] } }

পদ্ধতি 3 : মার্শাল.লোড - নেস্টেড কীগুলিতে মূল স্ট্রিং / প্রতীক মিশ্রণ সংরক্ষণ করে। পারফেক্ট!

Marshal.load( Marshal.dump(h) )
  => { :youtube => { :search => "daffy", "history" => ["goofy", "mickey"] } }

আমি অজানা এমন কোনও অপ্রতুলতা না থাকলে, আমি মনে করি পদ্ধতি 3টি যাওয়ার উপায়।

চিয়ার্স


2
এখানে অন্য কোনও গ্যারান্টি নেই যে আপনার অন্য পক্ষের নিয়ন্ত্রণ রয়েছে, সুতরাং আমি বিশ্বাস করি যে আপনাকে জেএসওএন ফর্ম্যাট করতে হবে। যদি আপনার উভয় পক্ষের পুরো নিয়ন্ত্রণ থাকে তবে মার্শাল প্রকৃতপক্ষে একটি ভাল ফর্ম্যাট, তবে এটি সাধারণ-উদ্দেশ্য সিরিয়ালকরণের জন্য উপযুক্ত নয়।
শীতল 42

5

কৌতুকটি করার জন্য এখানে কিছু অন্তর্নির্মিত নেই, তবে JSON রত্ন ব্যবহার করে কোডটি লিখতে খুব কঠিন নয়। symbolize_keysআপনি যদি এটি ব্যবহার করে থাকেন তবে রেলের মধ্যে একটি পদ্ধতি তৈরি করা হয়েছে, তবে এটি আপনার প্রয়োজন মতো পুনরাবৃত্তভাবে কীগুলি প্রতীকী নয়।

require 'json'

def json_to_sym_hash(json)
  json.gsub!('\'', '"')
  parsed = JSON.parse(json)
  symbolize_keys(parsed)
end

def symbolize_keys(hash)
  hash.inject({}){|new_hash, key_value|
    key, value = key_value
    value = symbolize_keys(value) if value.is_a?(Hash)
    new_hash[key.to_sym] = value
    new_hash
  }
end

লেভেনটিক্স যেমন বলেছে, জেএসওন রত্ন কেবলমাত্র ডাবল উদ্ধৃত স্ট্রিংগুলি পরিচালনা করে (যা প্রযুক্তিগতভাবে সঠিক - জেএসওএন ডাবল উদ্ধৃতি দিয়ে ফর্ম্যাট করা উচিত)। এই বিট কোডটি পার্স করার চেষ্টা করার আগে এটি পরিষ্কার হয়ে যাবে।


4

পুনরাবৃত্তির পদ্ধতি:

require 'json'

def JSON.parse(source, opts = {})
  r = JSON.parser.new(source, opts).parse
  r = keys_to_symbol(r) if opts[:symbolize_names]
  return r
end

def keys_to_symbol(h)
  new_hash = {}
  h.each do |k,v|
    if v.class == String || v.class == Fixnum || v.class == Float
      new_hash[k.to_sym] = v
    elsif v.class == Hash
      new_hash[k.to_sym] = keys_to_symbol(v)
    elsif v.class == Array
      new_hash[k.to_sym] = keys_to_symbol_array(v)
    else
      raise ArgumentError, "Type not supported: #{v.class}"
    end
  end
  return new_hash
end

def keys_to_symbol_array(array)
  new_array = []
  array.each do |i|
    if i.class == Hash
      new_array << keys_to_symbol(i)
    elsif i.class == Array
      new_array << keys_to_symbol_array(i)
    else
      new_array << i
    end
  end
  return new_array
end

1

অবশ্যই একটি জসন রত্ন রয়েছে তবে এটি কেবল ডাবল উদ্ধৃতি পরিচালনা করে।


মাদল্যাপ নীচে যেমন বলেছে - JSON বৈধ হবে (আপনি
নিজেরাই

এটি কাজ করে না। JSON.parse(JSON.generate([:a])) # => ["a"]
জাস্টিন এল।

2
কারণ JSON প্রতীক উপস্থাপন করতে পারে না। Marshal.load(Marshal.dump([:a]))পরিবর্তে আপনি ব্যবহার করতে পারেন:
লেভেনটিক্স

1

এটি পরিচালনা করার আরেকটি উপায় হ'ল ওয়াইএএমএল সিরিয়ালাইজেশন / ডিসরিয়ালাইজেশন ব্যবহার করা, যা কীটির বিন্যাসটিও সংরক্ষণ করে:

YAML.load({test: {'test' => { ':test' => 5}}}.to_yaml) 
=> {:test=>{"test"=>{":test"=>5}}}

এই পদ্ধতির সুবিধাটি এমন একটি ফর্ম্যাটের মতো বলে মনে হচ্ছে যা আরআরইএসটি পরিষেবার জন্য আরও উপযুক্ত ...


: কখনই YAML.load মধ্যে ব্যবহারকারীর ইনপুট করা যাক tenderlovemaking.com/2013/02/06/yaml-f7u12.html
Rafe

@ রাফা আপনি কি বোঝাতে চেয়েছেন যে 2013 এর এই সুরক্ষা গর্তটি আজও স্থির নয়?
বার্ট ব্রুইনোগে

1
প্রতীকগুলি ২.২-এর পর থেকে জিসি'ড হয় are YAML.loadস্বেচ্ছাসেবী অবজেক্টগুলিকে সিরিয়ালাইজ করতে বোঝানো হয় (যেমন ক্যাশের জন্য)। প্রস্তাবিতটি YAML.safe_loadসেই ব্লগ পোস্টের কয়েক মাস পরে প্রবর্তিত হয়েছে, সুতরাং এটি সঠিক জিনিসটি ব্যবহার করার বিষয়: github.com/ruby/psych/commit/…
রাফে

0

সর্বাধিক সুবিধাজনক উপায় হ'ল দুর্দান্ত_হ্যাশ রত্ন ব্যবহার করে: https://github.com/MarioRuiz/nice_hash

require 'nice_hash'
my_str = "{ 'user': { 'name': 'foo', 'age': 40, 'location': { 'city' : 'bar', 'state': 'ca' } } }"

# on my_hash will have the json as a hash
my_hash = my_str.json

# or you can filter and get what you want
vals = my_str.json(:age, :city)

# even you can access the keys like this:
puts my_hash._user._location._city
puts my_hash.user.location.city
puts my_hash[:user][:location][:city]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.