Nie jestem pewien, czy sortowanie skrótu ma dużą zaletę, chyba że używasz go eachlub each_pairiterujesz. Nawet wtedy pewnie nadal chwytałbym klucze, sortowałam je, a następnie powtarzałam je, chwytając wartości w razie potrzeby. To gwarantuje, że kod będzie działał poprawnie na starszych Rubinach.
Tin Man
Ma to również sens w Ruby 1.9. Miałem zbiór spotkań pogrupowanych według dat (jako kluczy) pochodzących z bazy danych i ręcznie posortowałem według ruby. Na przykład. {"2012-09-22": [...], "2012-09-30": [...], "2012-10-12": [...]}
Adit Saxena
Tak, uważam, że proces skrótu [h.sort] jest bardziej efektywny niż sortowanie kluczy, a następnie ponowne uzyskiwanie dostępu do skrótu przez posortowane klucze.
@zachaysan, ale to działa: h.sort{|a,z|a<=>z}.to_h(testowane 2.1.10, 2.3.3)
whitehat101
@ whitehat101 Masz rację. Miałem błąd ( ato tablica, nie tylko klucz). Usunąłem mój komentarz.
zachaysan
Tylko w przypadku, ktoś inny szuka sposobu, aby posortować tablicę skrótów, będzie to rade (gdzie h jest tablica) h.map(&:sort).map(&:to_h).
JM Janzen,
82
Uwaga: Ruby> = 1.9.2 ma hash zachowujący porządek: wstawiane klucze zamówień będą kolejnością, w której są wyliczane. Poniższe dotyczy starszych wersji lub kodu kompatybilnego wstecz.
Nie ma koncepcji posortowanego skrótu. Więc nie, to co robisz jest niewłaściwe.
Jeśli chcesz posortować do wyświetlenia, zwróć ciąg:
lub, jeśli chcesz uzyskać dostęp do elementów w kolejności:
h.sort.map do|key,value|# keys will arrive in order to this block, with their associated value.end
ale podsumowując, nie ma sensu mówić o posortowanym haszu. Z dokumentów : „Kolejność przechodzenia przez skrót lub klucz lub wartość może wydawać się dowolna i na ogół nie będzie w kolejności wstawiania”. Więc wstawienie kluczy w określonej kolejności do skrótu nie pomoże.
„Począwszy od wersji 1.9.2 kolejność wstawiania skrótu zostanie zachowana.” I jest ładna.
Tin Man,
2
Re mój pierwszy komentarz (zabawne): Na przykład poleganie na porządkowaniu haszowania po cichu i nieprzewidziany przerwie dla wersji Ruby starszych niż 1.9.2.
Jo Liss,
5
Jak ta odpowiedź uzyskała około 20 + 1 bez odpowiedzi nawet na jedną z dwóch części pytania PO? „1) Czy byłby to (na przykład OP) najlepszy sposób sortowania skrótu, 2) i zwracania obiektu Hash”? Nie zazdroszczę + 1-ek :) zaraz po przeczytaniu odpowiedzi wciąż mam oryginalne pytania. Także jeśli chodzi o to, że nie ma czegoś takiego jak posortowany skrót, spójrz na komentarze dla wybranej odpowiedzi stackoverflow.com/questions/489139/...
jj_
64
Zawsze używałem sort_by. Musisz owinąć dane #sort_bywyjściowe, Hash[]aby uzyskać wynik mieszania, w przeciwnym razie wyprowadza tablicę tablic. Alternatywnie, aby to osiągnąć, możesz uruchomić #to_hmetodę na tablicy krotek, aby przekonwertować je na k=>vstrukturę (skrót).
użycie sort_byskrótu zwróci tablicę. Będziesz musiał ponownie zmapować go jako skrót. Hash[hsh.sort_by{|k,v| v}]
stevenspiel
1
tak, klasa wyliczająca interpretuje skróty jako tablice, myślę
boulder_ruby
3
Prawo, porządek jest na wartości: hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}.
Cary Swoveland,
1
Zauważ, że dzwonienie to_hjest obsługiwane tylko w Ruby 2.1.0+
Phrogz
1
w komentarzu jest literówka, poprawka:sort_by{|k,v| v}.to_h)
fluktuacja
13
Nie, to nie jest (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 doHash[h.sort]endend
GC.start
b.report("keys sort")do
many.times do
nh ={}
h.keys.sort.each do|k|
nh[k]= h[k]endendendend
user system total real
hash sort 0.4000000.0000000.400000(0.405588)
keys sort 0.2500000.0100000.260000(0.260303)
W przypadku dużych skrótów różnica wzrośnie do 10x i więcej
Dałeś najlepszą odpowiedź sobie w OP: Hash[h.sort]jeśli pragniesz więcej możliwości, oto modyfikacja oryginalnego skrótu na miejscu, aby go posortować:
Naprawiłem link prowadzący do Google na wypadek, gdyby jakiś historyk chciał zbadać, jak można to zrobić w przeszłości. Ale każdy, kto przyjdzie na to teraz, powinien używać nowszej wersji Ruby.
Podobało mi się rozwiązanie we wcześniejszym poście.
Zrobiłem mini-klasę class AlphabeticalHash. Ma również sposób zwany ap, która przyjmuje jeden argument, Hashjako wejście: ap variable. Podobne do pp ( pp variable)
Ale to (spróbuje) wydrukować na liście alfabetycznej (jej klucze). Nie wiem, czy ktokolwiek chce tego użyć, jest dostępny jako klejnot, możesz go zainstalować w ten sposób:gem install alphabetical_hash
Dla mnie jest to dość proste. Jeśli inni potrzebują więcej funkcji, daj mi znać, włączę ją do klejnotu.
EDYCJA: Podziękowania należą się Peterowi , który podsunął mi pomysł. :)
each
lubeach_pair
iterujesz. Nawet wtedy pewnie nadal chwytałbym klucze, sortowałam je, a następnie powtarzałam je, chwytając wartości w razie potrzeby. To gwarantuje, że kod będzie działał poprawnie na starszych Rubinach.Odpowiedzi:
W Ruby 2.1 jest to proste:
źródło
h.sort{|a,z|a<=>z}.to_h
(testowane 2.1.10, 2.3.3)a
to tablica, nie tylko klucz). Usunąłem mój komentarz.h.map(&:sort).map(&:to_h)
.Uwaga: Ruby> = 1.9.2 ma hash zachowujący porządek: wstawiane klucze zamówień będą kolejnością, w której są wyliczane. Poniższe dotyczy starszych wersji lub kodu kompatybilnego wstecz.
Nie ma koncepcji posortowanego skrótu. Więc nie, to co robisz jest niewłaściwe.
Jeśli chcesz posortować do wyświetlenia, zwróć ciąg:
lub, jeśli chcesz klucze w kolejności:
lub, jeśli chcesz uzyskać dostęp do elementów w kolejności:
ale podsumowując, nie ma sensu mówić o posortowanym haszu. Z dokumentów : „Kolejność przechodzenia przez skrót lub klucz lub wartość może wydawać się dowolna i na ogół nie będzie w kolejności wstawiania”. Więc wstawienie kluczy w określonej kolejności do skrótu nie pomoże.
źródło
Zawsze używałem
sort_by
. Musisz owinąć dane#sort_by
wyjściowe,Hash[]
aby uzyskać wynik mieszania, w przeciwnym razie wyprowadza tablicę tablic. Alternatywnie, aby to osiągnąć, możesz uruchomić#to_h
metodę na tablicy krotek, aby przekonwertować je nak=>v
strukturę (skrót).Podobne pytanie znajduje się w „ Jak posortować Ruby Hash według wartości liczbowej? ”.
źródło
sort_by
skrótu zwróci tablicę. Będziesz musiał ponownie zmapować go jako skrót.Hash[hsh.sort_by{|k,v| v}]
hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
.to_h
jest obsługiwane tylko w Ruby 2.1.0+sort_by{|k,v| v}.to_h)
Nie, to nie jest (Ruby 1.9.x)
W przypadku dużych skrótów różnica wzrośnie do 10x i więcej
źródło
Dałeś najlepszą odpowiedź sobie w OP:
Hash[h.sort]
jeśli pragniesz więcej możliwości, oto modyfikacja oryginalnego skrótu na miejscu, aby go posortować:źródło
Z destrukcją i sortowaniem Hash
Wyliczalny # sort_by
Hash # sortuj z zachowaniem domyślnym
Uwaga: <Ruby 2.1
Uwaga:> Ruby 2.1
źródło
v
,hash.sort_by { |k, _v| k }.to_h
ActiveSupport :: OrdersHash to kolejna opcja, jeśli nie chcesz używać Ruby 1.9.2 lub tworzyć własnych obejść.
źródło
źródło
Miałem ten sam problem (musiałem posortować sprzęt według nazwy) i rozwiązałem w ten sposób:
@equipments to skrót, który buduję na moim modelu i zwracam na kontrolerze. Jeśli wywołasz .sort, posortuje skrót według jego kluczowej wartości.
źródło
Podobało mi się rozwiązanie we wcześniejszym poście.
Zrobiłem mini-klasę
class AlphabeticalHash
. Ma również sposób zwanyap
, która przyjmuje jeden argument,Hash
jako wejście:ap variable
. Podobne do pp (pp variable
)Ale to (spróbuje) wydrukować na liście alfabetycznej (jej klucze). Nie wiem, czy ktokolwiek chce tego użyć, jest dostępny jako klejnot, możesz go zainstalować w ten sposób:
gem install alphabetical_hash
Dla mnie jest to dość proste. Jeśli inni potrzebują więcej funkcji, daj mi znać, włączę ją do klejnotu.
EDYCJA: Podziękowania należą się Peterowi , który podsunął mi pomysł. :)
źródło