2010-03-25 28 views
6

Điều này sẽ được thực hiện trong Javascript (jQuery) nhưng tôi cho rằng phương pháp này có thể được sử dụng trong bất kỳ ngôn ngữ nào.Làm thế nào tôi có thể sắp xếp một mảng, nhưng loại trừ các phần tử nhất định (được giữ ở cùng vị trí trong mảng)

Tôi có một loạt các mục và tôi cần thực hiện sắp xếp. Tuy nhiên có một số mục trong mảng phải được giữ trong cùng một vị trí (cùng một chỉ mục).

Mảng được đề cập là xây dựng từ danh sách các phần tử <li> và tôi đang sử dụng giá trị .data() được gắn với mục danh sách làm giá trị để sắp xếp.

Cách tiếp cận nào sẽ tốt nhất ở đây?

<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> 

Tôi muốn các danh sách được sắp xếp với kết quả sau ...

<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> 

Cảm ơn!

Trả lời

6

Thuật toán là:

  • Extract và sắp xếp các mặt hàng không được đánh dấu với stay
  • Merge stay mục và sắp xếp các mặt hàng

    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

Đây là mã giống với những gì tôi đã kết thúc vì vậy tôi đã đánh dấu nó là đúng - Tôi chắc chắn giải pháp được cung cấp bởi petersendidit cũng tốt (mặc dù nó chưa được kiểm chứng). Cảm ơn! – calumbrodie

0

này sẽ không làm việc như Bevan chỉ ra, nhưng tôi sẽ để nó ở đây cho mục đích giáo dục:

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

Lưu ý: Bạn cần phải thiết lập các dữ liệu đường với 'đường' như là đối số tên:

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

Vấn đề với phương pháp này là các mặt hàng cố định trở thành rào cản đối với việc sắp xếp - bất kỳ mục nào bên dưới một điểm cố định sẽ không bao giờ di chuyển trên nó, và ngược lại. – Bevan

+0

Cảm ơn bạn đã chỉ ra lỗi cú pháp, tôi đã sửa mã ví dụ ở trên. – calumbrodie

1

Bạn đúng khi nghĩ rằng giải pháp là chung chung và có thể áp dụng cho bất kỳ môi trường phát triển nào.

Bạn sẽ cần phân vùng danh sách các phần tử của mình thành hai danh sách khác nhau - những danh sách cần sắp xếp và các danh sách sẽ được đặt đúng vị trí. Sau đó, sắp xếp danh sách đầu tiên và hợp nhất với danh sách thứ hai.

Vấn đề chính mà bạn đang gặp phải là: Hầu hết các thuật toán sắp xếp (bao gồm QuickSort, thuật toán phổ biến nhất được tìm thấy trong hầu hết các khung công tác) trở nên khá là xấu nếu chức năng so sánh của bạn dựa vào bất kỳ trạng thái bên ngoài nào).

+0

Tôi có nên sử dụng chức năng kết hợp jQuery hay nối các mảng và khu nghỉ dưỡng không? Làm cách nào để đảm bảo mảng các mục 'cố định' của tôi được ưu tiên khi chỉ mục giống nhau? Giải pháp mà bạn đề xuất chính là cách tôi đã cố gắng làm điều này trong lần đầu tiên nhưng tôi không thể làm cho nó hoạt động được. Ít nhất tôi biết tôi đã đi đúng hướng.Cảm ơn vì đầu vào của bạn! – calumbrodie

+0

Trả lời bởi @Konstantin có vẻ tốt với tôi (Javascript của tôi không phải là nhiệm vụ. +1) – Bevan

3

này nên làm điều đó:

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); 
    } 
} 

này lưu trữ các chỉ số của các mục có lớp nghỉ và sau đó nó sẽ thực hiện sắp xếp theo số điểm và sau đó thay thế các mục có lớp ở lại tại địa điểm chính xác.

Các vấn đề liên quan