簡體   English   中英

如何排序數組,但排除某些元素(保持在數組中的相同位置)

[英]How can I sort an array, yet exclude certain elements (to be kept at the same position in the array)

這將在Javascript(jQuery)中實現,但我想這個方法可以用於任何語言。

我有一系列項目,我需要進行排序。 但是 ,數組中的某些項必須保持在相同的位置(相同的索引)。

有問題的數組是從<li>元素列表構建的,我使用附加到列表項的.data()值作為要排序的值。

這方面最好的方法是什么?

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

謝謝!

算法是:

  • 提取並排序未標記為stay項目
  • 合並stay物品和分類物品

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

這應該這樣做:

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

這會緩存具有類保留的項目的索引,然后按分數進行排序,然后將類替換為保留在正確位置的類。

您認為該解決方案是通用的並適用於任何開發環境是正確的。

您需要將元素列表分成兩個不同的列表 - 要排序的列表和要保留的列表。 然后,對第一個列表進行排序並與第二個列表合並。

您面臨的關鍵問題是:如果您的比較函數依賴於任何外部狀態(如項目位置),則大多數排序算法(包括QuickSort ,這是大多數框架中最常見的算法)變得非常不良。

這不會像Bevan指出的那樣有效,但我會把它留在這里用於教育目的:

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

注意:您需要使用'sugar'作為name參數設置糖數據:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM