2010-08-04 3 views
4

Можно ли условно сортировать в хеше?Можно ли условно сортировать хэш?

Мой хэш быть как:

{1=>"10",2=>"20",3=>"30",4=>"40",5=>"50",6=>"60",7=>"70",8=>"80",9=>"90"} 

Желаемый результат:

{7=>"70",8=>"80",9=>"90",1=>"10",2=>"20",3=>"30",4=>"40",5=>"50",6=>"60"} 

добавить условие в этом коде

operation_hour_hash.sort{|key,value| key[1]<=>value[1]} 

ответ

3

Sur e, вы могли бы сделать что-то вроде:

>> {1=>"10",2=>"20",3=>"30",4=>"40",5=>"50",6=>"60",7=>"70",8=>"80",9=>"90"}.sort{|p,n| (p[1].to_i>=70 && n[1].to_i<70) ? -1 : (p[1].to_i<70 && n[1].to_i>=70) ? 1 : p[1].to_i <=> n[1].to_i} 

=> [[7, "70"], [8, "80"], [9, "90"], [1, "10"], [2, "20"], [3, "30"], [4, "40"], [5, "50"], [6, "60"]] 

Но сортировка хэша на самом деле не имеет большого смысла. Прежде чем сортировка на самом деле происходит, он преобразуется в массив из пар [ключ, значение], затем сортируется на -1,0,1, возвращенный с < =>.

Если вам нужны отсортированные хеши, вам нужно использовать что-то вроде RubyFacets Dictionary.

1

Ваш рода вызов в заблуждение. Вы не сравниваете ключ и значение, вы сравниваете два разных элемента массива. Так оно и должно быть:

operation_hour_hash.sort{|a,b| a[1]<=>b[1]} 

Вы можете реализовать любую логику вы хотите в каком-то этапе, до тех пор, как он прилипает к следующему:

Блок реализует сравнение между а и Ь, возвращаясь -1, 0 или +1

(взяты из: http://ruby-doc.org/core/classes/Array.html#M002185)

1

Вы можете попробовать что-то вроде этого, чтобы произвести отсортированный массив

operation_hour_hash.sort {|x,y| (x[0]>6?x[0]-6:x[0]+24)<=>(y[0]>6?y[0]-6:y[0]+24)} 
>> [[7, "70"], [8, "80"], [9, "90"], [1, "10"], [2, "20"], [3, "30"], [4, "40"], [5, "50"], [6, "60"]] 

Вы можете изменить условия, чтобы удовлетворить ваши потребности.

Однако будьте осторожны, чтобы в рубине 1.8 хеш не был заказан ключом. Если вы конвертируете обратно в хэш, заказ не гарантируется.