架构
var my_array = [
{
"title": "a",
"pinned": {
"status": "true",
"order": "1"
}
},
{
"title": "d",
"pinned": {
"status": "false",
"order": "n/a"
}
},
{
"title": "c",
"pinned": {
"status": "true",
"order": "0"
}
},
{
"title": "b",
"pinned": {
"status": "false",
"order": "n/a"
}
}
];
期望的行为
按字母title
对对象进行排序,
除非它们的pinned
状态为true
,
在这种情况下,将此项目的“子集”移到数组的开头,
按其pinned.order
值排序。
一个示例场景是一个论坛,该论坛的帖子按日期排序,但顶部的粘性帖子按定义的顺序排序。
因此,原始架构将显示为:
[
{// i am at the top, because i have a pinned status of true and order of 0
"title": "c",
"pinned": {
"status": "true",
"order": "0"
}
},
{// i am second from the top, because i have a pinned status of true and order of 1
"title": "a",
"pinned": {
"status": "true",
"order": "1"
}
},
{// i follow in alphabetical order
"title": "b",
"pinned": {
"status": "false",
"order": "n/a"
}
},
{// i follow in alphabetical order
"title": "d",
"pinned": {
"status": "false",
"order": "n/a"
}
}
]
我尝试过的事情
my_array.sort(function(a, b) {
return a.pinned.order.localeCompare(b.pinned.order) || a.title.localeCompare(b.title);
});
基于此答案:
https://stackoverflow.com/a/45741804
我也尝试过...
我考虑过根据pinned.status
的值创建两个单独的数组,分别对它们进行排序,然后重新组合(如下所示),但是我想知道是否还有更优雅的方法?
var my_array = [
{
"title": "a",
"pinned": {
"status": "true",
"order": "1"
}
},
{
"title": "d",
"pinned": {
"status": "false",
"order": "n/a"
}
},
{
"title": "c",
"pinned": {
"status": "true",
"order": "0"
}
},
{
"title": "b",
"pinned": {
"status": "false",
"order": "n/a"
}
}
];
var my_subset = [];
for (var i = 0; i < my_array.length; i++) {
if (my_array[i].pinned.status === "true") {
// add to subset
my_subset.push(my_array[i]);
// remove from original array
my_array.splice(i, 1);
}
}
// sort "pruned" original array alphabetically
my_array.sort(function(a, b) {
return a.title.localeCompare(b.title);
});
// sort subset array by pinned.order
my_subset.sort(function(a, b) {
return a.pinned.order.localeCompare(b.pinned.order, undefined, { numeric: true });
});
// prepend subset to original array
var new_array = my_subset.concat(my_array);
// array is sorted as desired
console.log(new_array);
答案 0 :(得分:2)
首先通过将数字字符串设为数字,并将布尔字符串设为布尔值来修复数据:
for (const item of my_array) {
item.pinned.status = JSON.parse(item.pinned.status);
item.pinned.order = Number(item.pinned.order);
}
现在,您不必将它们作为字符串进行比较。否则,您的方法基本上没问题,您只是忘记了最重要的指示符,即某项是否应该排在最前面:其pinned.status
。首先进行比较,以使任何固定的项目都在没有固定的项目之前。
my_array.sort(function(a, b) {
return -(a.pinned.status - b.pinned.status) // reverse: true before false
|| (a.pinned.status // equal to b.pinned.status
? a.pinned.order - b.pinned.order
: a.title.localeCompare(b.title));
});
var my_array = [{
"title": "a",
"pinned": {
"status": true,
"order": 1
}
},
{
"title": "d",
"pinned": {
"status": false,
"order": 0
}
},
{
"title": "c",
"pinned": {
"status": true,
"order": 0
}
},
{
"title": "b",
"pinned": {
"status": false,
"order": 0
}
}
];
my_array.sort(function(a, b) {
return -(a.pinned.status - b.pinned.status) // reverse: true before false
||
(a.pinned.status // equal to b.pinned.status
?
a.pinned.order - b.pinned.order :
a.title.localeCompare(b.title));
});
console.log(my_array);
您也可以
my_array.sort(function(a, b) {
return -(a.pinned.status - b.pinned.status) // reverse: true before false
|| a.pinned.order - b.pinned.order
|| a.title.localeCompare(b.title);
});
由于未固定的项目具有相同的顺序(NaN
),但前者更为明确。
答案 1 :(得分:1)
只需尝试一下:
my_array.sort(function(a, b) {
return a.title.localeCompare(b.title);
}).sort(function(a, b) {
return a.pinned.order.localeCompare(b.pinned.order)
});
答案 2 :(得分:0)
如果可以使用Lodash(Java实用程序库),则可以使用orderBy或sortBy:
在项目中使用Lodash:
<script src="lodash.js"></script>
使用orderBy进行排序:
_.orderBy(my_array, [function(e) { return e.pinned.status}, 'title'], ['asc', 'asc']);
答案 3 :(得分:0)
去那里:
hereIWantTheFrequencyValue
提取var my_array = [
{
"title": "a",
"pinned": {
"status": "true",
"order": "1"
}
},
{
"title": "d",
"pinned": {
"status": "false",
"order": "n/a"
}
},
{
"title": "c",
"pinned": {
"status": "true",
"order": "0"
}
},
{
"title": "b",
"pinned": {
"status": "false",
"order": "n/a"
}
}
];
var trueArr = [];
var falseArr = [];
var titleArr = [];
var tempArr = []
for(var obj of my_array){
if(obj.pinned.status == "true"){
trueArr.push(obj);
}else{
falseArr.push(obj);
}
}
function sortArr(arr){
titleArr = [];
tempArr = [];
for(var obj of arr){
titleArr.push(obj.title);
}
titleArr = titleArr.sort();
for(var counter = 0; counter < arr.length; counter++){
tempArr.push(null);
}
for(var obj of arr){
tempArr[titleArr.indexOf(obj.title)] = obj;
}
for(counter = 0; counter < tempArr.length; counter++){
arr[counter] = tempArr[counter];
}
}
function addTrueFalseArr(arr){
for (var obj of arr){
my_array.push(obj)
}
}
sortArr(trueArr);
my_array = [];
addTrueFalseArr(trueArr);
sortArr(falseArr);
addTrueFalseArr(falseArr);
处的所有对象,并将它们放入数组中。然后对pinned = true
所在的对象执行相同的操作。然后,根据标题对两个数组进行排序(按字母顺序),然后将原始数组设置为空数组-> pinned = false
,然后将[]
项附加到原始数组,最后附加{ {1}}个项目。