Ruby on Rails'de bir dizi nesnem var. Diziyi nesnenin bir özelliğine göre sıralamak istiyorum. Mümkün mü?
Ruby on Rails'de bir dizi nesnem var. Diziyi nesnenin bir özelliğine göre sıralamak istiyorum. Mümkün mü?
Yanıtlar:
Bunun yerine sort_by kullanmanızı öneririm:
objects.sort_by {|obj| obj.attribute}
Özellikle öznitelik hesaplanabiliyorsa.
Veya daha özlü bir yaklaşım:
objects.sort_by(&:attribute)
objects.sort_by { |obj| obj.attribute.downcase }
sort!
(örneğin hız, vb.)?
Evet, bunu kullanmak Array#sort!
çok kolay.
myarray.sort! { |a, b| a.attribute <=> b.attribute }
<=>
? Ne tür hatalar alıyorsun? vb, vb, ve mide bulantısı. Başka bir deyişle, "ama benim için şans yok" dan daha fazla ayrıntıya ihtiyacımız var.
sort
Orijinali korumak ve sonucu farklı bir nesneye atamak istiyorsanız kullanın ; aksi takdirde, yerinde varyantı kullanın sort!
. Aslında, orijinal nesneyi kopyaladıktan sonra dahili olarak sort
arama yapar sort!
.
sort!
iyi çalışacağını garanti edebilirim ve her zaman (!) Yazdıklarınızla aynı şeyi yapın.
Artan sıra:
objects_array.sort! { |a, b| a.attribute <=> b.attribute }
veya
objects_array.sort_by{ |obj| obj.attribute }
Azalan sipariş :
objects_array.sort! { |a, b| b.attribute <=> a.attribute }
veya
objects_array.sort_by{ |obj| obj.attribute }.reverse
iki özniteliğe göre sıralamanız gerekirse, burada birincisi daha önemli, sonra ikincisi (ikinci argümanları yalnızca ilk argümanlar eşitse hesaba katmak anlamına gelir), o zaman bunu yapabilirsiniz
myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 }
veya dizi dizisi durumunda
myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] }
<=> yöntemini geçersiz kılarak herhangi bir sınıfı sıralanabilir hale getirebilirsiniz:
class Person
attr_accessor :first_name, :last_name
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
def <=>(other)
@last_name + @first_name <=> other.last_name + other.first_name
end
end
Artık bir dizi Person nesnesi last_name üzerinde sıralanabilir.
ar = [Person.new("Eric", "Cunningham"), Person.new("Homer", "Allen")]
puts ar # => [ "Eric Cunningham", "Homer Allen"] (Person objects!)
ar.sort!
puts ar # => [ "Homer Allen", "Eric Cunningham" ]
Dizi # sıralaması, yukarıda yayınlandığı gibi iyi çalışır:
myarray.sort! { |a, b| a.attribute <=> b.attribute }
ANCAK, <=>
operatörün bu öznitelik için uygulandığından emin olmanız gerekir . Ruby yerel veri türüyse, bu bir sorun değildir. Aksi takdirde, a <b ise -1, eşitse 0 ve a> b ise 1 döndüren kendi uygulamanızı yazın.
Daha zarif objects.sort_by(&:attribute)
, .reverse
siparişi değiştirmeniz gerekirse bir de ekleyebilirsiniz .
@model_name.sort! { |a,b| a.attribute <=> b.attribute }
sort
Doğrudan karşılaştırılamayan nesneleri sıralarken kullanmayın . Özniteliklere erişmeniz veya bir hesaplama yapmanız gerekiyorsa, değeri karşılaştırmak için kullanın sort_by
. Çok daha hızlı olacak.
objects.sort_by(&:attribute)