Posiadam tablice asosjacyjna np. taka: [{2=>3143324097}, {1=>4443451015}, {1=>1243933918}, {1=>8258069620}, {1=>8143561896}, {2=>1143622476}, {1=>7843636204}]. Chciałbym ją posortować po kluczu (mam na myśli pierwszą wartość, w tym wypadku 2 lub 1). Wykonuje to przy pomocy tablica.sort_by { |klucz, wartosc| klucz } - w efekcie dostaje: comparison of Hash with Hash failed. W wypadku gdy posortuję ja po wartości tj. tablica.sort_by { |klucz, wartosc| wartosc } - dostaje ładnie posortowaną tablicę względem wartość.
Czy orientuje się ktoś jak mogę ją ułożyć względem tak mało różniących się “kluczy” ?
To co masz, to nie jest tablica asocjacyjna, tylko zwykła tablica, której elementami są tablice asocjacyjne.
Aby posortować to po “kluczu” należy zrobić tak:
tablica.sort_by{|hash| hash.keys.first }
tablica.sort { |x,y| x.keys.first <=> y.keys.first }
Dziękuję bardzo. To co napisaliście działa. Pomyślałem sobie jednak, że bez sensu robić tablice, a w niej tablice asosjacyjne. W teh chwili robię to tak
tablica = Hash.new
cos.each do |t|
tablica.push(t)
end
Jak mógłbym wykonać analogiczną operację, aby w wyniku otrzymać {klucz0 => wartosc0, klucz1 => wartosc1, …, kluczn => wartoscn} ?
Może na przykład:
hash = {}
cos.each { |x| hash.merge!(x) }
Wracając do tematu sortowania, chciałbym posortować taką tablicę
{120230=>13, 120232=>11, 550232=>1}
po kluczu (tj. co do kolejności pierwszej wartości)
w ten sposób:
@tab.sort_by{|hash| hash.keys.first }
jednak dostaje błąd: undefined method `keys’ for [120230, 13]:Array
W jaki sposób można posortować taką tabicę ?
@tab.sort_by {|el| el[1] }
Wytłumaczenie: do bloku nie podajesz całego hasha tylko element, i blok ma zwrócić wartość, po której ma być sortowanie, czyli do bloku trafia pierwszy element hasha, który w środku jest tablicą 2-elementową : [klucz, wartość] - więc musisz sortować po drugim elemencie takiej tablicy.
Dzięki za wytłumaczenie. Jeszcze jedna rzecz mnie zastanawia, w efekcie dostaję tablicę dwu-wymiarowa (zwykłą, a nie asocjacyjną). Możesz mi wytłumaczyć dlaczego tak się dzieje.
Najprościej - bo metoda sort_by jest metodą nie tyle klasy Hash, co mixowanego do niej modułu Enumerable. Oprócz tego, Hash w zamyśle nie miał być uporządkowaną strukturą danych. Dopiero od wersji 1.9 języka hash w ogóle “zapamiętuje”, w jakiej kolejności jego klucze są definiowane - wcześniej tego nie robił.
Hm, nie wiem jaki był powód tego, że tak zrobiono. Generalnie metody sortujące w rubym (nie wiem czy wszystkie, ale sprawdzałem na hashach i setach) zwracają posortowaną tablicę - nie odbudowują typu, na którym wywołano metodę.
żeby zbudować hash z takiej tablicy (gdzie każdy element jest tablicą 2-elementową) użyj takiej składni:
1.9.3-p327 :018 > ary = [["a",1],["b",2]]
=> [["a", 1], ["b", 2]]
1.9.3-p327 :019 > Hash[ary]
=> {"a"=>1, "b"=>2}
Lypa ma rację, zapewne to wynikało z tego, że hash nie gwarantował trzymania kolejności w wersjach < 1.9.x - tak samo set może tego nie gwarantować