Sıralama, en başından beri bilgisayar bilimcileri için bir endişeydi. Çok fazla vardı algoritmalar ve bugün hala yeni algoritmalar performansın sınırlarını zorluyor. Üst düzey bir dil olarak, sınıflandırma algoritmalarını Yakut performansı önemsiyor ve sıralamanın yanı sıra Diziler ve diğer koleksiyonlar Ruby'nin sizin için yaptığı daha çok şey.
Teknik olarak, sıralama Enumerable modülü tarafından ele alınan bir iştir. Numaralandırılabilir modül, Ruby'deki tüm koleksiyon türlerini birbirine bağlayan modüldür. Koleksiyonlar üzerinde yineleme, sıralama, belirli öğelere bakmak ve bulmak vb. Numaralandırılabilir bir koleksiyonun nasıl sıralandığı biraz gizemdir, ya da en azından öyle kalmalıdır. Gerçek sıralama algoritması önemsizdir, bilmeniz gereken tek şey koleksiyondaki nesnelerin "uzay gemisi operatörü" kullanılarak karşılaştırılmasıdır.
"Uzay gemisi operatörü" iki nesneyi alır, karşılaştırır ve sonra -1, 0 veya 1 değerini döndürür. Bu biraz belirsiz, ancak operatörün kendisi çok iyi tanımlanmış bir davranışa sahip değil. Örneğin Sayısal nesneleri ele alalım. İki sayısal nesneniz varsa
bir ve bve değerlendir a <=> b, ifade neye göre değerlendirilecek? Nümerikler söz konusu olduğunda bunu söylemek kolaydır. A b'den büyükse -1, eşitse 0 olur ve b a'dan büyükse 1 olur. Bu, sıralama algoritmasına iki nesneden hangisinin önce dizi. Sadece sol taraftaki işlenen dizide birinci olacaksa -1 olarak değerlendirmelidir, sağ el önce olmalı 1 olmalıdır ve eğer önemli değilse 0 olmalıdır.Her zaman böyle düzenli kurallara uymaz. Bu operatörü farklı türde iki nesne üzerinde kullanırsanız ne olur? Muhtemelen bir istisna alacaksınız. Aradığın zaman ne olur 1 <=> 'maymun'? Bu, aramaya eşdeğer olacak 1. <=> ( 'Maymun), yani gerçek yöntem, ayrıldı işlenen ve Fixnum # <=> sağ işlenen sayısal değilse nil döndürür. İşleç nil döndürürse, sort yöntemi bir istisna oluşturur. Bu nedenle, dizileri sıralamadan önce, sıralanabilir nesneler içerdiğinden emin olun.
İkincisi, uzay gemisi operatörünün gerçek davranışı tanımlanmamıştır. Sadece bazı temel sınıflar için tanımlanmıştır ve özel sınıflarınız için, onların ne anlama gelmesini istediğiniz tamamen size bağlıdır. Eğer bir Öğrenci sınıf soyad, ad, sınıf seviyesi veya bunların bir kombinasyonuna göre öğrenci sıralaması yapabilirsiniz. Bu nedenle, uzay gemisi operatörünün ve sıralamanın davranışının temel türler dışında hiçbir şey için iyi tanımlanmadığını daima unutmayın.
Sayısal nesne diziniz var ve bunları sıralamak istiyorsunuz. Bunu yapmak için iki temel yöntem vardır: çeşit ve çeşit!. Birincisi dizinin bir kopyasını oluşturur, diziyi sıralar ve döndürür. İkincisi diziyi yerinde sıralar.
Bu oldukça açıklayıcı. Öyleyse bir çentik alalım. Uzay gemisi operatörüne güvenmek istemezseniz ne olur? Tamamen farklı bir davranış istiyorsanız? Bu iki sıralama yöntemi isteğe bağlı bir blok parametresi alır. Bu blok iki parametre alır ve uzay gemisi operatörünün yaptığı gibi değerler vermelidir: -1, 0 ve 1. Bu nedenle, bir dizi verildiğinde, onu 3'e bölünebilir tüm değerler önce gelir ve diğerleri sonra gelir. Asıl düzen burada önemli değil, sadece 3 ile bölünebilenlerin önce gelmesi.
Bu nasıl çalışıyor? İlk olarak, sort yöntemine ilişkin blok bağımsız değişkenini not edin. İkinci olarak, blok parametreleri üzerinde yapılan modulo bölümlerine ve uzay gemisi operatörünün yeniden kullanımına dikkat edin. Biri 3'ün katı ise, modulo 0 olur, aksi takdirde 1 veya 2 olur. 0, 1 veya 2'den önce sıralanacağından, burada sadece modulo önemlidir. Bir blok parametresi kullanmak, özellikle birden fazla öğe türüne sahip dizilerde veya tanımlanmış bir uzay gemisi operatörü bulunmayan özel sınıflarda sıralamak istediğinizde kullanışlıdır.
Bir tane daha sıralama yöntemi var, göre sırala. Ancak, sort_by ile mücadele etmeden önce, dizileri ve koleksiyonları harita ile çevirmeyi anlamalısınız.