Это будет реализовано в 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) {{{ 1}} $ (this) .data ('sugar', sugarcontent [i]);
// Показываем количество сахара в тексте каждого элемента - для целей отладки
if ($ (this). hasClass ('остаться'))
$ (это) .text ("s" + $ (this) .text ());
else
$ (this) .text (sugarcontent [i] + "" + $ (this) .text ());
});
// Сортировка сортируемых элементов
var sorted = $ (items) .filter (': not (.stay)'). sort (function (l, r) {
return $ (l) .data ('sugar') - $ (r) .data ('сахар');
});
// Объединить оставшиеся элементы и отсортированные элементы
var result = [];
var sortedIndex = 0;
for (var i = 0; i
Это должно сработать:
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);
}
}
Это кэширует индекс элементов с классом, а затем выполняет сортировку по количеству очков, а затем заменяет элементы классом, оставшимся в правильном месте.
Это не будет работать, как указал Беван, но я оставлю это здесь в образовательных целях:
$('#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 с 'sugar' в качестве аргумента name:
.data('sugar', sugarcontent[i]);
Вы правы, думая, что решение является общим и применимо к любой среде разработки.
Вам нужно разделить список элементов на два разных списка - те, которые нужно отсортировать, и те, которые нужно оставить на месте. Затем отсортировать первый список и объединить со вторым.
Основная проблема, с которой вы столкнулись, заключается в следующем: Большинство алгоритмов сортировки (включая QuickSort, который является наиболее распространенным в большинстве фреймворков) становятся весьма нехорошими, если ваша функция сравнения полагается на какое-либо внешнее состояние (например, позицию элемента).