Javascript - 如何按 3 种不同的属性类型对对象数组进行排序? (字符串、整数、布尔值)
Posted
技术标签:
【中文标题】Javascript - 如何按 3 种不同的属性类型对对象数组进行排序? (字符串、整数、布尔值)【英文标题】:Javascript - How to sort array of object by 3 different attributes type? (String, Integer, Boolean) 【发布时间】:2019-02-06 09:05:00 【问题描述】:我有一个对象数组:
var a = [
"name": "BBB", "no": 2, "size1": [3], "size2": null ,
"name": "AAA", "no": 5, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": [2], "size2": null ,
"name": "AAA", "no": 4, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": null, "size2": [1] ,
"name": "AAA", "no": 5, "size1": [2], "size2": null ,
"name": "BBB", "no": 2, "size1": null, "size2": [1] ,
];
我想这样排序,按name
升序排序,然后no
升序排序,如果不为空则按size1。
一开始我可以按name
和no
排序,但之后我不知道如何按size1
或size2
排序。如果不为空,则应首先按 size1 排序。
这是我要排序的代码
function sortObject(arrayObjects)
arrayObjects.sort(function(a,b)
if(a.name=== b.name)
return (a.no - b.no);
else if(a.name > b.name)
return 1;
else if(a.name < b.name)
return -1;
);
预期结果
var a = [
"name": "AAA", "no": 4, "size1": null, "size2": [1] ,
"name": "AAA", "no": 5, "size1": [2], "size2": null ,
"name": "AAA", "no": 5, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": [2], "size2": null ,
"name": "BBB", "no": 1, "size1": null, "size2": [1] ,
"name": "BBB", "no": 2, "size1": [3], "size2": null ,
"name": "BBB", "no": 2, "size1": null, "size2": [1] ,
]
【问题讨论】:
当size1
是null
时,你希望它做什么?你什么时候使用size2
?
是的,如果 size1 为空,那么我使用 size2。每个对象只有 Size1 或 Size2。我只需要先按 size1 排序,然后按 size2 排序。看起来像按名称和否分组
【参考方案1】:
您可以从 30 秒的代码(我维护的一个项目/网站)中使用 orderBy
的修改版本,它还会检查 null
并相应地订购:
var a = [
"name": "BBB", "no": 2, "size1": [3], "size2": null ,
"name": "AAA", "no": 5, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": [2], "size2": null ,
"name": "AAA", "no": 4, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": null, "size2": [1] ,
"name": "AAA", "no": 5, "size1": [2], "size2": null ,
"name": "BBB", "no": 2, "size1": null, "size2": [1] ,
];
const orderBy = (arr, props, orders) =>
[...arr].sort((a, b) =>
props.reduce((acc, prop, i) =>
if (acc === 0)
const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]];
acc = p1 === null ? 1 : p2 === null ? -1 : p1 > p2 ? 1 : p1 < p2 ? -1 : 0;
return acc;
, 0)
);
var aSorted = orderBy(a, ['name', 'no', 'size1', 'size2'], ['asc', 'asc', 'asc', 'asc']);
console.log(aSorted);
orderBy
的工作原理:
在props
数组上使用Array.sort()
、Array.reduce()
,默认值为0
,使用数组解构根据传递的顺序交换属性位置。如果没有传递orders
数组,则默认按'asc'
排序。
【讨论】:
【参考方案2】:你可以这样做
-
用于字符串比较
String.prototype.localeCompare()
对于数字/数组长度减法
演示
const arr = [
"name": "BBB", "no": 2, "size1": [3], "size2": null ,
"name": "AAA", "no": 5, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": [2], "size2": null ,
"name": "AAA", "no": 4, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": null, "size2": [1] ,
"name": "AAA", "no": 5, "size1": [2], "size2": null ,
"name": "BBB", "no": 2, "size1": null, "size2": [1] ,
];
arr.sort((a, b) =>
let check = a.name.localeCompare(b.name);
if (check == 0)
check = a.no - b.no;
if (check == 0)
check = (b.size1 || []).length - (a.size1 || []).length;
return check;
);
console.log(arr)
.as-console-wrapper max-height: 100% !important;top: 0;
【讨论】:
【参考方案3】:你可以试试这样的:
var a = [
"name": "AAA", "no": 4, "size1": null, "size2": [1] ,
"name": "AAA", "no": 5, "size1": [2], "size2": null ,
"name": "AAA", "no": 5, "size1": null, "size2": [1] ,
"name": "BBB", "no": 1, "size1": [2], "size2": null ,
"name": "BBB", "no": 1, "size1": null, "size2": [1] ,
"name": "BBB", "no": 2, "size1": [3], "size2": null ,
"name": "BBB", "no": 2, "size1": null, "size2": [1] ,
]
a.sort(function(a, b)
return a.name.localeCompare(b.name) ||
a.no - b.no ||
(b.size1 === null) - (a.size1 === null) ||
(b.size2 === null) - (a.size2 === null)
);
console.log(a)
【讨论】:
【参考方案4】:您必须在您的第一个 if
中比较 no
:
function sortObject(arrayObjects)
arrayObjects.sort(function(a,b)
if (a.name=== b.name)
if (a.no === b.no)
// Determines which size to use for comparison
const aSize = a.size1 || a.size2;
const bSize = b.size1 || b.size2;
return (aSize[0] - bSize[0]);
return (a.no - b.no);
else if (a.name > b.name)
return 1;
else if (a.name < b.name)
return -1;
);
【讨论】:
null
支票呢?
null
的期望是什么?
size1
可以是null
。如果你执行null - [3]
- 在这种情况下你会得到什么结果?
我刚刚使用问题的 cmets 中提供的详细信息更新了我的答案。
请注意,这些“大小”属性看起来像是数组,而不是普通数字。以上是关于Javascript - 如何按 3 种不同的属性类型对对象数组进行排序? (字符串、整数、布尔值)的主要内容,如果未能解决你的问题,请参考以下文章