Below code is used to sort arrays as shown just below:
下面的代码用于排序数组,如下所示:
function sorter(a, b) {
if((b.dataset.type === 'Recommended') && (a.dataset.type === 'Recommended'))
return (b.dataset.type === 'Recommended') - (a.dataset.type === 'Recommended') || a.dataset.amount - b.dataset.amount;
if((b.dataset.type === 'Featured') && (a.dataset.type === 'Featured'))
return (b.dataset.type === 'Featured') - (a.dataset.type === 'Featured') || a.dataset.amount - b.dataset.amount;
if((b.dataset.type === 'Special Offer') && (a.dataset.type === 'Special Offer'))
return (b.dataset.type === 'Special Offer') - (a.dataset.type === 'Special Offer') || a.dataset.amount - b.dataset.amount;
if((b.dataset.type === 'Christmas') && (a.dataset.type === 'Christmas'))
return (b.dataset.type === 'Christmas') - (a.dataset.type === 'Christmas') || a.dataset.amount - b.dataset.amount;
if((b.dataset.type === '') && (a.dataset.type === ''))
return (b.dataset.type === '') - (a.dataset.type === '') || a.dataset.amount - b.dataset.amount;
}
var sortedDivs = $(".terminalpopular").toArray().sort(sorter);
I have sorted an array based on different types (i.e. recommended, featured, christmas and no type) labeled on the divs, as below:
我根据div上标记的不同类型(即推荐,特色,圣诞节和无类型)对数组进行了排序,如下所示:
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
I wanted to sort it as per below (INTENDED RESULT):
我想按照以下排序(预期结果):
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
Demonstration in words:
用语言示范:
Can you suggest that how can I sort the array based on types in such way. i.e. Recommended have values of 84, 74, 64 and we have Featured type as well and having values of 78, 68, 88. Can we sort it in such form: 64 (recommended), 68 (featured), 74(recommended), 78 (featured), 84(recommended), 88 (featured) etc and son on ?
您能否建议我如何以这种方式基于类型对数组进行排序。即推荐的值为84,74,64,我们也有特色类型,值为78,68,88。我们可以用以下形式对它进行排序:64(推荐),68(特色),74(推荐), 78(特色),84(推荐),88(特色)等和儿子?
2 个解决方案
#1
1
Below is a sample of the kind of arrangement you wanted.
以下是您想要的安排样本。
In my understanding, using 1 sort function will be difficult here, so have broken the problems in stages. Due to this, following solution might take many extra iteration.
根据我的理解,在这里使用1种排序功能将很困难,因此分阶段打破了问题。因此,以下解决方案可能需要进行许多额外的迭代。
var emptyList = '__EMPTY__';
function processElements() {
var list = $('.terminalpopular');
var clone = list.clone();
var groupedList = createGroups(clone);
var sortedGroups = sortGroups(groupedList);
var arrangedList = arrangeElements(sortedGroups);
list.parent().empty().append(arrangedList)
}
// Create groups based on type
function createGroups(list) {
return Array.from(list).reduce(function(p, c){
var type = c.dataset.type || emptyList;
p[type] = p[type] || [];
p[type].push(c);
return p;
}, Object.create(null));
}
// Sort each group by amount
function sortGroups(list) {
function sortFn(a, b) {
return Number(a.dataset.amount) - Number(b.dataset.amount);
}
for (var k in list) {
list[k].sort(sortFn);
}
return list;
}
// Rearrange elements based on index
function arrangeElements(sortedList) {
var list = [];
var max = Math.max.apply(null, Object.keys(sortedList)
.filter(x => x !== emptyList)
.map(x => sortedList[x].length)
);
for(var i = 0; i< max; i++) {
list = list.concat(Object.keys(sortedList)
.filter(x => x !== emptyList)
.map(x => sortedList[x][i])
);
}
list = list.concat(sortedList[emptyList]);
return list;
}
// This is only for display purpose
function displayValue() {
$('.terminalpopular').each(function(i, el) {
$(el).text($(el).data('amount'));
if ($(el).data('type')) {
$(el).addClass('highlight')
}
})
}
displayValue();
processElements();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div>
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>
#2
1
You can use sort()
method and first sort by data type
property and then by amount
.
您可以使用sort()方法,首先按数据类型属性排序,然后按金额排序。
var sorted = $(".parent > div").sort(function(a, b) {
return ($(b).data('type') != '') - ($(a).data('type') != '') || +$(a).data('amount') - +$(b).data('amount')
})
$('.parent').html(sorted)
// Just for demo
$('.parent > div').each(function() {
$(this).text($(this).data('amount'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>
Update Create object with keys based on types and value as array of elements with those types, then sort those values based on amount then loop each object property and add to parent element.
更新使用基于类型和值的键创建对象作为具有这些类型的元素数组,然后根据数量对这些值进行排序,然后循环每个对象属性并添加到父元素。
var obj = {}
$('.parent > div').each(function() {
var type = $(this).data('type');
if (type == '') type = 'empty';
if (!obj[type]) obj[type] = [];
obj[type].push($(this))
})
for (var i in obj) obj[i].sort(function(a, b) {
return $(a).data('amount') - $(b).data('amount')
})
$('.parent').empty();
var max = Object.keys(obj).reduce(function(r, e) {
var l = obj[e].length;
if (r == null || l > obj[r].length) r = e
return r;
}, null)
obj[max].forEach(function(e, i) {
Object.keys(obj).forEach(function(k) {
if (k != 'empty' && obj[k][i]) $('.parent').append(obj[k][i])
})
})
$('.parent').append(...obj['empty'])
$('.parent > div').each(function() {
$(this).text($(this).data('amount') + ' ' + $(this).data('type'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>
#1
1
Below is a sample of the kind of arrangement you wanted.
以下是您想要的安排样本。
In my understanding, using 1 sort function will be difficult here, so have broken the problems in stages. Due to this, following solution might take many extra iteration.
根据我的理解,在这里使用1种排序功能将很困难,因此分阶段打破了问题。因此,以下解决方案可能需要进行许多额外的迭代。
var emptyList = '__EMPTY__';
function processElements() {
var list = $('.terminalpopular');
var clone = list.clone();
var groupedList = createGroups(clone);
var sortedGroups = sortGroups(groupedList);
var arrangedList = arrangeElements(sortedGroups);
list.parent().empty().append(arrangedList)
}
// Create groups based on type
function createGroups(list) {
return Array.from(list).reduce(function(p, c){
var type = c.dataset.type || emptyList;
p[type] = p[type] || [];
p[type].push(c);
return p;
}, Object.create(null));
}
// Sort each group by amount
function sortGroups(list) {
function sortFn(a, b) {
return Number(a.dataset.amount) - Number(b.dataset.amount);
}
for (var k in list) {
list[k].sort(sortFn);
}
return list;
}
// Rearrange elements based on index
function arrangeElements(sortedList) {
var list = [];
var max = Math.max.apply(null, Object.keys(sortedList)
.filter(x => x !== emptyList)
.map(x => sortedList[x].length)
);
for(var i = 0; i< max; i++) {
list = list.concat(Object.keys(sortedList)
.filter(x => x !== emptyList)
.map(x => sortedList[x][i])
);
}
list = list.concat(sortedList[emptyList]);
return list;
}
// This is only for display purpose
function displayValue() {
$('.terminalpopular').each(function(i, el) {
$(el).text($(el).data('amount'));
if ($(el).data('type')) {
$(el).addClass('highlight')
}
})
}
displayValue();
processElements();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div>
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>
#2
1
You can use sort()
method and first sort by data type
property and then by amount
.
您可以使用sort()方法,首先按数据类型属性排序,然后按金额排序。
var sorted = $(".parent > div").sort(function(a, b) {
return ($(b).data('type') != '') - ($(a).data('type') != '') || +$(a).data('amount') - +$(b).data('amount')
})
$('.parent').html(sorted)
// Just for demo
$('.parent > div').each(function() {
$(this).text($(this).data('amount'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>
Update Create object with keys based on types and value as array of elements with those types, then sort those values based on amount then loop each object property and add to parent element.
更新使用基于类型和值的键创建对象作为具有这些类型的元素数组,然后根据数量对这些值进行排序,然后循环每个对象属性并添加到父元素。
var obj = {}
$('.parent > div').each(function() {
var type = $(this).data('type');
if (type == '') type = 'empty';
if (!obj[type]) obj[type] = [];
obj[type].push($(this))
})
for (var i in obj) obj[i].sort(function(a, b) {
return $(a).data('amount') - $(b).data('amount')
})
$('.parent').empty();
var max = Object.keys(obj).reduce(function(r, e) {
var l = obj[e].length;
if (r == null || l > obj[r].length) r = e
return r;
}, null)
obj[max].forEach(function(e, i) {
Object.keys(obj).forEach(function(k) {
if (k != 'empty' && obj[k][i]) $('.parent').append(obj[k][i])
})
})
$('.parent').append(...obj['empty'])
$('.parent > div').each(function() {
$(this).text($(this).data('amount') + ' ' + $(this).data('type'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="terminalpopular" data-amount="65.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="70" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="94.95" data-type="Recommended">…</div>
<div class="terminalpopular" data-amount="67.99" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="75" data-type="Featured">…</div>
<div class="terminalpopular" data-amount="78" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="84.99" data-type="Christmas">…</div>
<div class="terminalpopular" data-amount="54.95" data-type>…</div>
<div class="terminalpopular" data-amount="84.99" data-type>…</div>
</div>