2010-03-25 20 views
6

Bu, Javascript'te (jQuery) uygulanacaktır, ancak yöntemin herhangi bir dilde kullanılabileceğini varsayalım.Bir diziyi nasıl sıralayabilirim, ancak bazı öğeleri (dizide aynı konumda tutulacak) hariç tutabilirsiniz

Bir dizi ürünüm var ve bir sıralama yapmam gerekiyor. Ancak, dizisinde, aynı konumda (aynı dizin) tutulması gereken bazı öğeler vardır.

Söz konusu dizi, <li> öğelerinin bir listesinden oluşturulur ve sıralamak istediğiniz değer olarak liste öğesine eklenen .data() değerlerini kullanıyorum.

Burada en iyi yaklaşım hangisidir?

aşağıdaki sonuçla sıralanmış listesini istiyorum
<ul id="fruit"> 
    <li class="stay">bananas</li> 
    <li>oranges</li> 
    <li>pears</li> 
    <li>apples</li> 
    <li class="stay">grapes</li> 
    <li>pineapples</li> 
</ul> 

<script type="text/javascript"> 
    var sugarcontent = new Array('32','21','11','45','8','99'); 
    $('#fruit li').each(function(i,e){ 
     $(this).data('sugar',sugarcontent[i]); 
    }) 
</script> 

...

<ul id="fruit"> 
     <li class="stay">bananas</li> <!-- score = 32 --> 
     <li>pineapples</li> <!-- score = 99 --> 
     <li>apples</li> <!-- score = 45 --> 
     <li>oranges</li> <!-- score = 21 --> 
     <li class="stay">grapes</li> <!-- score = 8 --> 
     <li>pears</li> <!-- score = 11 --> 
    </ul> 

teşekkürler!

cevap

6

Algortimasıdır:

  • Özü ve stay
  • Birleştirme stay öğelerle işaretlenmemiş öğeleri sıralamak ve ayıklanmış ürün

    var sugarcontent = new Array(32, 21, 11, 45, 8, 99); 
    
    var items = $('#fruit li'); 
    
    items.each(function (i) { 
        $(this).data('sugar', sugarcontent[i]); 
        // Show sugar amount in each item text - for debugging purposes 
        if ($(this).hasClass('stay')) 
         $(this).text("s " + $(this).text()); 
        else 
         $(this).text(sugarcontent[i] + " " + $(this).text()); 
    }); 
    
    // Sort sortable items 
    var sorted = $(items).filter(':not(.stay)').sort(function (l, r) { 
        return $(l).data('sugar') - $(r).data('sugar'); 
    }); 
    
    // Merge stay items and sorted items 
    var result = []; 
    var sortedIndex = 0; 
    
    for (var i = 0; i < items.length; i++) 
        if (!$(items[i]).hasClass('stay')) { 
         result.push(sorted[sortedIndex]); 
         sortedIndex++; 
        } 
        else 
         result.push(items[i]); 
    
    // Show result 
    $('#fruit').append(result); 
    
+0

Bu benim en çok neye benzediğimi anlatan koddur, bu yüzden doğru olarak işaretledim - Eminim petersendidit tarafından sağlanan çözüm de (test edilmemiş olsa da) iyidir. Teşekkürler! – calumbrodie

0

Bevan belirttiği gibi bu işe yaramaz, ama eğitim amaçlı burada bırakacağım:

$('#fruit li').sort(function(a, b) { 
    return ($(a).hasClass('stay') || $(b).hasClass('stay')) 
     ? 0 : (a.data('sugar') > b.data('sugar') ? 1 : -1); 
}).appendTo('#fruit'); 

Not: Eğer isim argüman olarak 'şeker' ile şeker verilerini ayarlamanız gerekir:

.data('sugar', sugarcontent[i]); 
+3

Bu yaklaşımdaki sorun olduğu tespit ürün olduğunu sıralamada engeller olmak - sabit bir noktanın altındaki herhangi bir öğe asla üstünün üstüne çıkmayacak ve bunun tersi olacaktır. – Bevan

+0

Sözdizimi hatasını belirttiğinizde, yukarıdaki örnek kodumu düzeltdim. – calumbrodie

1

Çözümün genel olduğunu ve herhangi bir geliştirme ortamına uygulanabilir olduğunu düşünerek haklısınız.

Öğelerinizin listesini iki farklı listeye ayırmanız gerekir - sıralanacak olanlar ve yerine bırakılacak olanlar. Ardından, ilk listeyi sıralayın ve ikinci ile birleştirin.

Karşılaştığınız temel sorun şudur: Çoğu sıralama algoritması (çoğu çerçevede bulunan en yaygın olanı olan QuickSort dahil), karşılaştırma işleviniz herhangi bir harici duruma (öğe konumu gibi) dayanıyorsa oldukça hatalı davranır.).

+0

jQuery birleştirme işlevini kullanmalı mı yoksa dizileri ve başvuruyu birleştirmeli miyim? Dizinler aynı olduğunda, 'sabit' öğeler dizilimimin önceliğini almasını nasıl sağlayabilirim? Teklif ettiğin çözüm tam olarak bunu ilk defa yapmaya çalıştığımdı ama işe yaramaya yetişemedim. En azından doğru yolda olduğumu biliyorum.Girdiniz için teşekkürler! – calumbrodie

+0

Tarafından cevap @Konstantin bana iyi görünüyor (benim Javascript göreve göre değil. +1) – Bevan

3

Bu yapmalıyım:

var sugarcontent = new Array('32','21','11','45','8','99'); 
var list = $('#fruit'); 
var lis = list.find('li').each(function(i,e){ 
    $(this).data('score',sugarcontent[i]); 
}); 
var stay = lis.filter('.stay').each(function(){ 
    $(this).data('index',$(this).index()); 
}); 
lis.sort(function(a,b){ 
    return $(b).data('score') - $(a).data('score'); 
}).appendTo(list); 
stay.each(function(){ 
    var index = $(this).data('index'); 
    if (index == 0) { 
     list.prepend(this); 
    } else { 
     lis.filter(':eq('+index+')').insertAfter(this); 
    } 
} 

Bu sınıf konaklama ile öğelerin dizinini önbelleğe ve daha sonra skora göre sıralama yapar ve daha sonra sınıf ile ürün geri doğru yerde kalmak yerine geçer.

İlgili konular