[英]javascript - sort only certain elements of array according to position in another array
[英]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.