Bu, bir hashı sıralamanın ve Hash nesnesini (Array yerine) döndürmenin en iyi yolu olurdu:
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}
Bu, bir hashı sıralamanın ve Hash nesnesini (Array yerine) döndürmenin en iyi yolu olurdu:
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}
Yanıtlar:
Ruby 2.1'de basit:
h.sort.to_h
h.sort{|a,z|a<=>z}.to_h
(test 2.1.10, 2.3.3)
a
bir dizi, sadece anahtar). Yorumumu sildim.
h.map(&:sort).map(&:to_h)
.
Not: Ruby> = 1.9.2'de bir sipariş koruma karması vardır: girilen sipariş anahtarları numaralandıkları sıra olacaktır. Aşağıdakiler eski sürümler veya geriye dönük uyumlu kod için geçerlidir.
Sıralanmış bir karma kavramı yoktur. Yani hayır, yaptığınız doğru değil.
Görüntülenmek üzere sıralanmasını istiyorsanız bir dize döndürün:
"{" + h.sort.map{|k,v| "#{k.inspect}=>#{v.inspect}"}.join(", ") + "}"
veya anahtarları sırayla istiyorsanız:
h.keys.sort
veya öğelere sırayla erişmek istiyorsanız:
h.sort.map do |key,value|
# keys will arrive in order to this block, with their associated value.
end
ancak özet olarak, sıralı bir karma hakkında konuşmak mantıklı değildir. Gönderen docs , "ya anahtar veya değere göre bir karma çapraz sırası keyfi görünebilir ve genellikle kampanya siparişinde olmayacaktır." Bu nedenle, anahtarları belirli bir sırada karmaya eklemek yardımcı olmaz.
Hep kullandım sort_by
. Sen sarmak gerekir #sort_by
ile çıktı Hash[]
aksi takdirde diziler içeren bir dizi verir, bu çıkış bir karma yapmak. Alternatif olarak, bunu gerçekleştirmek için #to_h
yöntemi bir k=>v
yapıya (karma) dönüştürmek için tuples dizisinde çalıştırabilirsiniz .
hsh ={"a" => 1000, "b" => 10, "c" => 200000}
Hash[hsh.sort_by{|k,v| v}] #or hsh.sort_by{|k,v| v}.to_h
Benzer bir soru, " Ruby Hash'i sayı değerine göre nasıl sıralayabilirim? "
sort_by
karma üzerinde kullanmak bir dizi döndürür. Tekrar karma olarak eşlemeniz gerekir. Hash[hsh.sort_by{|k,v| v}]
hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
.
to_h
sadece 2.1.0+ Ruby desteklenir
sort_by{|k,v| v}.to_h)
Hayır, değil (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)
Büyük karmalar için fark 10x ve daha fazla büyür
OP'de kendinize en iyi cevabı verdiniz: Hash[h.sort]
Daha fazla olasılık için can atıyorsanız, orijinal karma işleminin sıralanmasını sağlamak için yerinde değişiklik:
h.keys.sort.each { |k| h[k] = h.delete k }
Hash anahtarına göre sırala , Ruby'de karma döndür
İle strüktür ve Hash # çeşit
hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h
Enumerable # sort_by
hash.sort_by { |k, v| k }.to_h
Varsayılan davranışla karma # sıralama
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 }
Not: <Yakut 2.1
array = [["key", "value"]]
hash = Hash[array]
hash #=> {"key"=>"value"}
Not:> Yakut 2.1
[["key", "value"]].to_h #=> {"key"=>"value"}
v
bir altçizgi önekini hash.sort_by { |k, _v| k }.to_h
ActiveSupport :: OrderedHash , yakut 1.9.2 kullanmak veya kendi geçici çözümlerinizi almak istemiyorsanız başka bir seçenektir.
@ordered = {}
@unordered.keys.sort.each do |key|
@ordered[key] = @unordered[key]
end
Aynı sorunu yaşadım (ekipmanımı isimlerine göre sıralamak zorunda kaldım) ve şu şekilde çözdüm:
<% @equipments.sort.each do |name, quantity| %>
...
<% end %>
@equipment benim model üzerinde inşa ve denetleyicime dönmek bir karma. .Sort öğesini çağırırsanız, karma değerini anahtar değerine göre sıralar.
Önceki yazıda çözümü beğendim.
Mini bir sınıf yaptım, denir class AlphabeticalHash
. Ayrıca, bir ap
bağımsız değişkeni, a Hash
, giriş olarak kabul eden bir yöntem vardır ap variable
. Akıntıya pp ( pp variable
)
Ancak, alfabetik listede (anahtarları) yazdırmaya çalışacaktır. Başka kimse bunu kullanmak istiyorsa, bir mücevher olarak kullanılabilir, bu şekilde yükleyebilirsiniz:gem install alphabetical_hash
Benim için bu yeterince basit. Diğerlerinin daha fazla işlevselliğe ihtiyacı varsa, bana bildirin, gemiye dahil edeceğim.
EDIT: Kredi bana fikir veren Peter gidiyor . :)
each
veyaeach_pair
üzerinde yineleme yapmadığınız sürece bir hashı sıralamanın çok avantajı olduğundan emin değilim . O zaman bile, muhtemelen hala anahtarları alıyorum, bunları sıralıyordum, daha sonra değerleri gerektiği gibi yakaladım. Bu, kodun eski Ruby'lerde doğru şekilde çalışmasını sağlar.