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