কী দ্বারা হ্যাশ বাছাই করুন, রুবিতে ফেরত হ্যাশ


257

এটি হ্যাশ বাছাই এবং হ্যাশ অবজেক্ট (অ্যারের পরিবর্তে) ফেরত দেওয়ার সর্বোত্তম উপায় হবে:

h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4}
# => {"a"=>1, "c"=>3, "b"=>2, "d"=>4}

Hash[h.sort]
# => {"a"=>1, "b"=>2, "c"=>3, "d"=>4}

9
আমি নিশ্চিত না যে হ্যাশ বাছাই করার অনেক সুবিধা রয়েছে, যদি না আপনি ব্যবহার করছেন eachবা each_pairএটির উপরে পুনরাবৃত্তি না করেন। তারপরেও, আমি সম্ভবত এখনও কীগুলি ধরব, সেগুলিকে বাছাই করুন, তারপরে পুনরুক্তি করুন প্রয়োজনীয়গুলি মানগুলি ধরে ফেলতে। এটি নিশ্চিত করে যে কোডটি পুরানো রুবিসের সাথে সঠিকভাবে আচরণ করবে।
টিন ম্যান

রুবি 1.9 এও বোঝায়। আমার কাছে ডিবি থেকে আগত তারিখগুলি (কী হিসাবে) গ্রুপযুক্ত অ্যাপয়েন্টমেন্টগুলির সংকলন ছিল এবং আমি নিজে রুবীর মাধ্যমে বাছাই করেছি। যেমন। 2012 "2012-09-22": [...], "2012-09-30": [...], "2012-10-12": [...]
Ad

হ্যাঁ, আমি আপনার হ্যাশ [এইচএসআর্ট] প্রসেসটি চাবি বাছাই করার চেয়ে আরও কার্যকরভাবে কার্যকারিতা দেখতে পাচ্ছি যাতে আবার হ্যাশ ট্রটকে বাছাই করা কীগুলি অ্যাক্সেস করতে হবে।
ডগলাস


3
আপনার সমাধান সম্পর্কে ভাবতে আপনার কয়েক বছর কেটে গেছে, আপনি কি কোনও উত্তর গ্রহণ করতে প্রস্তুত? ;-)
মার্ক থমাস

উত্তর:


219

রুবি ২.১ এ এটি সহজ:

h.sort.to_h

@ জাচায়সান তবে এটি কাজ করে: h.sort{|a,z|a<=>z}.to_h(পরীক্ষিত 2.1.10, 2.3.3)
হোয়াইটহ্যাট 101

পছন্দ করেছেন আমার একটি বাগ ছিল ( aএকটি অ্যারে, কেবল কী নয়)। আমি আমার মন্তব্য মুছে ফেলেছি।
জাচায়সান

হ্যাশ এর একটি অ্যারের বাছাই করতে যদি অন্য একজনকে একটি উপায় খুঁজছে, এই কৌতুক (যেখানে জ অ্যারের হয়) যা করবেন: h.map(&:sort).map(&:to_h)
জেএম জানজেন

82

দ্রষ্টব্য: রুবি> = 1.9.2 এর একটি অর্ডার-সংরক্ষণের হ্যাশ রয়েছে: ক্রম কীগুলি সন্নিবেশ করা হবে সেগুলি হবে তারা অঙ্কিত ক্রম। নীচে পুরানো সংস্করণ বা পশ্চাদপটে সামঞ্জস্যপূর্ণ কোডে প্রযোজ্য।

বাছাই করা হ্যাশটির কোনও ধারণা নেই। সুতরাং না, আপনি যা করছেন তা ঠিক নয়।

আপনি যদি এটি প্রদর্শনের জন্য বাছাই করতে চান তবে একটি স্ট্রিং ফিরিয়ে দিন:

"{" + h.sort.map{|k,v| "#{k.inspect}=>#{v.inspect}"}.join(", ") + "}"

বা, যদি আপনি চাবিগুলি ক্রমে চান:

h.keys.sort

বা, আপনি যদি উপাদানগুলিকে ক্রমে অ্যাক্সেস করতে চান:

h.sort.map do |key,value|
  # keys will arrive in order to this block, with their associated value.
end

তবে সংক্ষেপে, এটি একটি সাজানো হ্যাশ সম্পর্কে কথা বলার কোনও মানে করে না। দস্তাবেজগুলি থেকে , "আপনি যে কী বা মান দ্বারা একটি হ্যাশকে অতিক্রম করেছেন তার ক্রমটি স্বেচ্ছাসেবী মনে হতে পারে এবং সাধারণত সন্নিবেশ ক্রমে থাকবে না।" সুতরাং হ্যাশটিতে একটি নির্দিষ্ট ক্রমে কীগুলি প্রবেশ করানো সাহায্য করবে না।


এটা সঠিক। আমি রুবিতে অর্ডার সেট কার্যকারিতা অর্জন করার জন্য আরবিট্রি রত্নটি ব্যবহার করার পরামর্শ দেব।
অ্যারন স্ক্র্যাগস

26
1.9.2 থেকে শুরু করে হ্যাশ সন্নিবেশ ক্রম সংরক্ষণ করা হবে। দেখুন redmine.ruby-lang.org/issues/show/994
ডেভিড

4
"1.9.2 হ্যাশ inোকানোর ক্রম শুরু করা সংরক্ষণ করা হবে" ", এবং এটি মিষ্টি।
টিন ম্যান

2
আমার প্রথম মন্তব্যটি (মজাদার অনুভূতি) পুনরায় করুন: উদাহরণস্বরূপ, হ্যাশ অর্ডারের উপর নির্ভর করা নিঃশব্দে এবং অপ্রত্যাশিতভাবে রুবি সংস্করণগুলি 1.9.2 এর চেয়ে পুরানো সংস্করণগুলির জন্য বিরতি দেবে।
জো লিস

5
ওপি প্রশ্নের দুটি অংশের একটিও উত্তর না দিয়ে কীভাবে এই উত্তরটি প্রায় 20 + 1 পেয়েছে? "1) হ্যাশ অবজেক্টটি সাজানোর এবং হ্যাশ অবজেক্টটি ফেরত দেওয়ার জন্য (ওপি উদাহরণ) কি সেরা উপায় হবে"? আমি +1 এর vyর্ষা করি না :) এর উত্তরটি পড়ার ঠিক পরে আমি এখনও মূল প্রশ্নগুলি রেখে এসেছি। এছাড়াও যদি বিন্দু সেখানে একটি সাজানো হ্যাশ এই প্রশ্নের choosen উত্তরের জন্য কোন মন্তব্য নেই বর্ণন যেমন জিনিস নয় যে stackoverflow.com/questions/489139/...
jj_

64

আমি সবসময় ব্যবহার করেছি sort_by। এটির একটি হ্যাশ আউটপুট তৈরি করতে আপনাকে #sort_byআউটপুটটি মোড়ানো Hash[]করতে হবে, অন্যথায় এটি অ্যারের একটি অ্যারে আউটপুট করে। বিকল্পভাবে, এটি সম্পাদন করার জন্য আপনি #to_hটিপলসের অ্যারেতে একটি পদ্ধতিতে k=>v(হ্যাশ) রূপান্তর করতে এই পদ্ধতিটি চালাতে পারেন ।

hsh ={"a" => 1000, "b" => 10, "c" => 200000}
Hash[hsh.sort_by{|k,v| v}] #or hsh.sort_by{|k,v| v}.to_h

" সংখ্যার মান অনুসারে একটি রুবি হ্যাশ কীভাবে বাছাই করবেন? " তে একই প্রশ্ন রয়েছে ।


8
sort_byএকটি হ্যাশ ব্যবহার করে একটি অ্যারে ফিরে আসবে। আপনার এটি আবার হ্যাশ হিসাবে মানচিত্রের প্রয়োজন হবে।Hash[hsh.sort_by{|k,v| v}]
স্টিভেনস্পিল 20

1
হ্যাঁ, গণক শ্রেণি হ্যাশগুলিকে আমার মনে হয় অ্যারে হিসাবে ব্যাখ্যা করে
গণক বোল্ডার_রবি

3
ঠিক আছে, সাজানোর মান হয়: hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
কেরি সোভেল্যান্ড

1
দ্রষ্টব্য যে কলিং to_hকেবলমাত্র রুবি ২.১.০++
ফ্রোগ্জে

1
: সেখানে মন্তব্য, সংশোধন একটি টাইপো হয়sort_by{|k,v| v}.to_h)
নার্ভাসভাবে

13

না, এটি নয় (রুবি 1.9.x)

require 'benchmark'

h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4}
many = 100_000

Benchmark.bm do |b|
  GC.start

  b.report("hash sort") do
    many.times do
      Hash[h.sort]
    end
  end

  GC.start

  b.report("keys sort") do
    many.times do
      nh = {}
      h.keys.sort.each do |k|
        nh[k] = h[k]
      end
    end
  end
end

       user     system      total        real
hash sort  0.400000   0.000000   0.400000 (  0.405588)
keys sort  0.250000   0.010000   0.260000 (  0.260303)

বড় হ্যাশগুলির জন্য পার্থক্য 10x এবং আরও বেশি বাড়বে


12

আপনি ওপিতে নিজেকে সেরা উত্তর দিয়েছেন: Hash[h.sort]আপনি যদি আরও বেশি সম্ভাবনার সন্ধান করেন তবে এটির বাছাই করতে এখানে মূল হ্যাশটির স্থান-পরিবর্তন রয়েছে:

h.keys.sort.each { |k| h[k] = h.delete k }

1
কৌতূহলের জন্য, এটি রুবি ১.৯.৩-এ স্ট্যাকওভারফ্লো.com/a/17331221/737303 এ "কী সারণি " থেকে কিছুটা দ্রুত গতিতে চলেছে ।
নাইট্রোজেন

9

কী দ্বারা হ্যাশ বাছাই করুন , রুবিতে ফেরত হ্যাশ

সঙ্গে ডেসট্রাকচারিং এবং হ্যাশ # সাজানোর

hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h

গণনীয় # sort_by

hash.sort_by { |k, v| k }.to_h

ডিফল্ট আচরণের সাথে হ্যাশ # সাজানো

h = { "b" => 2, "c" => 1, "a" => 3  }
h.sort         # e.g. ["a", 20] <=> ["b", 30]
hash.sort.to_h #=> { "a" => 3, "b" => 2, "c" => 1 }

দ্রষ্টব্য: <রুবি ২.১

array = [["key", "value"]] 
hash  = Hash[array]
hash #=> {"key"=>"value"}

দ্রষ্টব্য:> রুবি ২.১

[["key", "value"]].to_h #=> {"key"=>"value"}

1
আপনি যদি না ব্যবহার করেন তবে vএকটি আন্ডারস্কোর উপসর্গ করা উচিতhash.sort_by { |k, _v| k }.to_h
silva96

6

অ্যাক্টিভসপোর্ট :: আপনি রুবি ১.৯.২ ব্যবহার করতে বা নিজের কাজের ক্ষেত্র রোল করতে না চাইলে অর্ডারহ্যাশ হ'ল আরেকটি বিকল্প।


লিঙ্কটি নষ্ট হয়েছে
স্নেক স্যান্ডার্স

3
কিছু inতিহাসিক অতীতে কীভাবে এটি করা যেত তা গবেষণা করতে চাইলে আমি গুগলের প্রতি ইঙ্গিত করার লিংকটি স্থির করেছিলাম। তবে এখন যে কেউ এই বিষয়ে আসছেন তিনি রুবির একটি সাম্প্রতিক সংস্করণ ব্যবহার করা উচিত।
ইরাইমেট

0
@ordered = {}
@unordered.keys.sort.each do |key|
  @ordered[key] = @unordered[key]
end

4
রুবির যদি হ্যাশ # সাজানোর_বিধির মত পদ্ধতি না পান
পাথর_রবি

0

আমার একই সমস্যা ছিল (তাদের নাম অনুসারে আমার সরঞ্জামগুলি বাছাই করতে হয়েছিল) এবং আমি এর মতো সমাধান করেছি:

<% @equipments.sort.each do |name, quantity| %>
...
<% end %>

@ একুইপমেন্টস হ্যাশ যা আমি আমার মডেলটিতে তৈরি করি এবং আমার নিয়ামকটিতে ফিরে আসি। যদি আপনি কল করেন s


-3

আমি আগের পোস্টে সমাধানটি পছন্দ করেছি।

আমি একটি মিনি-ক্লাস তৈরি করেছি, এটি বলে class AlphabeticalHash। এটি একটি পদ্ধতি বলা apহয়, যা একটি আর্গুমেন্ট, একটি গ্রহণ Hash, ইনপুট হিসাবে: ap variable। আকিন থেকে পিপি (pp variable )

তবে এটি বর্ণানুক্রমিক তালিকায় (এর কীগুলি) মুদ্রণ করবে (চেষ্টা করুন)। ডুনো যদি অন্য কেউ এটি ব্যবহার করতে চায় তবে এটি রত্ন হিসাবে উপলব্ধ, আপনি এটি ইনস্টল করতে পারেন:gem install alphabetical_hash

আমার জন্য, এটি যথেষ্ট সহজ। অন্যের যদি আরও কার্যকারিতা প্রয়োজন হয় তবে আমাকে জানান, আমি এটি মণির মধ্যে অন্তর্ভুক্ত করব।

সম্পাদনা: ক্রেডিট পিটারের কাছে যায় , যিনি আমাকে ধারণা দিয়েছেন। :)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.