นี่เป็นวิธีที่ดีที่สุดในการเรียงลำดับแฮชและส่งคืนวัตถุแฮช (แทนที่จะเป็นอาร์เรย์) หรือไม่:
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}
นี่เป็นวิธีที่ดีที่สุดในการเรียงลำดับแฮชและส่งคืนวัตถุแฮช (แทนที่จะเป็นอาร์เรย์) หรือไม่:
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}
คำตอบ:
ใน Ruby 2.1 มันง่ายมาก:
h.sort.to_h
h.sort{|a,z|a<=>z}.to_h
(ทดสอบ 2.1.10, 2.3.3)
a
เป็นอาร์เรย์ไม่ใช่แค่กุญแจ) ฉันลบความคิดเห็นแล้ว
h.map(&:sort).map(&:to_h)
A:
หมายเหตุ: Ruby> = 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
แต่โดยสรุปแล้วมันไม่มีเหตุผลที่จะพูดถึงแฮชที่เรียงลำดับแล้ว จากเอกสาร "ลำดับที่คุณใช้แฮชโดยคีย์หรือค่าอาจดูไม่ได้โดยพลการและโดยทั่วไปจะไม่อยู่ในลำดับการแทรก" ดังนั้นการแทรกกุญแจตามลำดับเฉพาะลงในแฮชจะไม่ช่วย
sort_by
ผมเคยใช้เสมอ คุณจำเป็นต้องตัด#sort_by
เอาท์พุทด้วยHash[]
เพื่อให้มันส่งออกแฮมิฉะนั้นจะส่งออกอาร์เรย์ของอาร์เรย์ อีกวิธีหนึ่งเพื่อให้บรรลุนี้คุณสามารถเรียกใช้#to_h
วิธีการในอาร์เรย์ของ tuples เพื่อแปลงให้เป็น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
มีคำถามคล้ายกันใน " วิธีจัดเรียง Ruby Hash ตามค่าตัวเลข "
sort_by
แฮชจะส่งคืนอาร์เรย์ คุณจะต้องแมปแฮชอีกครั้ง Hash[hsh.sort_by{|k,v| v}]
hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
ขวาจัดเรียงอยู่บนค่า:
to_h
สามารถใช้ได้กับ Ruby 2.1.0+ เท่านั้น
sort_by{|k,v| v}.to_h)
ไม่มันไม่ใช่ (Ruby 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)
สำหรับความแตกต่างของแฮ็ชขนาดใหญ่จะเพิ่มขึ้นเป็น 10 เท่าและมากกว่า
คุณให้คำตอบที่ดีที่สุดสำหรับตัวคุณเองใน OP: Hash[h.sort]
หากคุณต้องการความเป็นไปได้มากขึ้นนี่คือการดัดแปลงแฮชแบบดั้งเดิมเพื่อให้เรียงลำดับ:
h.keys.sort.each { |k| h[k] = h.delete k }
เรียงลำดับแฮชตามคีย์แล้วส่งคืนแฮชใน Ruby
ด้วยdestructuringและ Hash # sort
hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h
นับ # sort_by
hash.sort_by { |k, v| k }.to_h
Hash # sort พร้อมพฤติกรรมเริ่มต้น
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 }
หมายเหตุ: <Ruby 2.1
array = [["key", "value"]]
hash = Hash[array]
hash #=> {"key"=>"value"}
หมายเหตุ:> Ruby 2.1
[["key", "value"]].to_h #=> {"key"=>"value"}
v
คุณควรใส่เครื่องหมายขีดล่างไว้hash.sort_by { |k, _v| k }.to_h
ActiveSupport :: OrderedHashเป็นอีกตัวเลือกหนึ่งหากคุณไม่ต้องการใช้ ruby 1.9.2 หรือแก้ไขปัญหาของคุณเอง
@ordered = {}
@unordered.keys.sort.each do |key|
@ordered[key] = @unordered[key]
end
ฉันมีปัญหาเดียวกัน (ฉันต้องเรียงลำดับอุปกรณ์ตามชื่อของพวกเขา) และฉันแก้ไขเช่นนี้:
<% @equipments.sort.each do |name, quantity| %>
...
<% end %>
@equipments เป็นแฮชที่ฉันสร้างในแบบจำลองของฉันและกลับไปที่คอนโทรลเลอร์ของฉัน หากคุณโทรหา. มันจะเรียงลำดับแฮชตามค่าของมัน
ฉันชอบวิธีแก้ปัญหาในโพสต์ก่อนหน้า
class AlphabeticalHash
ฉันทำมินิคลาสเรียกมันว่า นอกจากนี้ยังมีวิธีการที่เรียกว่าap
ซึ่งยอมรับอาร์กิวเมนต์หนึ่งที่Hash
เป็น ap variable
input: คล้ายกับ pp ( pp variable
)
แต่มันจะ (ลองและ) พิมพ์ในรายการตัวอักษร (กุญแจ) Dunno ถ้าใครต้องการใช้มันใช้ได้มันเป็นอัญมณีคุณสามารถติดตั้งได้เช่น:gem install alphabetical_hash
สำหรับฉันมันง่ายพอ หากผู้อื่นต้องการฟังก์ชั่นเพิ่มเติมแจ้งให้ฉันทราบฉันจะรวมไว้ในอัญมณี
แก้ไข: เครดิตไปถึงปีเตอร์ซึ่งทำให้ฉันมีความคิด :)
each
หรือวนeach_pair
ซ้ำ ถึงอย่างนั้นฉันก็ยังอาจคว้ากุญแจเรียงลำดับแล้วทำซ้ำพวกเขาคว้าค่าตามที่ต้องการ เพื่อให้แน่ใจว่ารหัสจะทำงานอย่างถูกต้องในทับทิมเก่า