grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;
});
所以上面的代码按gsize对数组进行排序 - 从最小到最大。它运作良好。 但如果gsize是相同的,我希望它然后按发光排序。
感谢。
答案 0 :(得分:97)
grouperArray.sort(function (a, b) {
return a.gsize - b.gsize || a.glow - b.glow;
});
较短版本
答案 1 :(得分:75)
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
if(aSize == bSize)
{
return (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0;
}
else
{
return (aSize < bSize) ? -1 : 1;
}
});
答案 2 :(得分:11)
我意识到这是前一段时间被问过的,但我想我会添加我的解决方案。
此函数动态生成排序方法。只需提供每个可排序的子属性名称,前面加上+/-表示升序或降序。超级可重用,并且不需要了解您已组合在一起的数据结构。可以做出白痴证明 - 但似乎没有必要。
function getSortMethod(){
var _args = Array.prototype.slice.call(arguments);
return function(a, b){
for(var x in _args){
var ax = a[_args[x].substring(1)];
var bx = b[_args[x].substring(1)];
var cx;
ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1;
bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1;
if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;}
if(ax != bx){return ax < bx ? -1 : 1;}
}
}
}
示例用法:
items.sort(getSortMethod(&#39; -price&#39;,&#39; + priority&#39;,&#39; + name&#39;));
这会首先将items
排序为最低price
,并将关联转到priority
最高的项目。项目name
其中items是一个数组:
var items = [
{ name: "z - test item", price: "99.99", priority: 0, reviews: 309, rating: 2 },
{ name: "z - test item", price: "1.99", priority: 0, reviews: 11, rating: 0.5 },
{ name: "y - test item", price: "99.99", priority: 1, reviews: 99, rating: 1 },
{ name: "y - test item", price: "0", priority: 1, reviews: 394, rating: 3.5 },
{ name: "x - test item", price: "0", priority: 2, reviews: 249, rating: 0.5 } ...
];
现场演示:http://gregtaff.com/misc/multi_field_sort/
编辑:修复了Chrome的问题。
答案 3 :(得分:8)
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);
使用箭头语法的更短版本!
答案 4 :(得分:6)
我希望ternary运算符((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;)
让您感到困惑。您应该查看链接以更好地理解它。
在那之前,这是你的代码被吹成完整的if / else。
grouperArray.sort(function (a, b) {
if (a.gsize < b.gsize)
{
return -1;
}
else if (a.gsize > b.gsize)
{
return 1;
}
else
{
if (a.glow < b.glow)
{
return -1;
}
else if (a.glow > b.glow)
{
return 1;
}
return 0;
}
});
答案 5 :(得分:3)
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : ( (aLow < bLow ) ? -1 : (aLow > bLow ) ? 1 : 0 );
});
答案 6 :(得分:3)
这是一个针对那些可能需要更通用的东西的实现,可以使用任意数量的字段。
Array.prototype.sortBy = function (propertyName, sortDirection) {
var sortArguments = arguments;
this.sort(function (objA, objB) {
var result = 0;
for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) {
var propertyName = sortArguments[argIndex];
result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0;
//Reverse if sort order is false (DESC)
result *= !sortArguments[argIndex + 1] ? 1 : -1;
}
return result;
});
}
基本上,您可以指定任意数量的属性名称/排序方向:
var arr = [{
LastName: "Doe",
FirstName: "John",
Age: 28
}, {
LastName: "Doe",
FirstName: "Jane",
Age: 28
}, {
LastName: "Foo",
FirstName: "John",
Age: 30
}];
arr.sortBy("LastName", true, "FirstName", true, "Age", false);
//Will return Jane Doe / John Doe / John Foo
arr.sortBy("Age", false, "LastName", true, "FirstName", false);
//Will return John Foo / John Doe / Jane Doe
答案 7 :(得分:3)
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0); });
答案 8 :(得分:2)
使用多个键进行操作的动态方式:
Object.defineProperty(Array.prototype, 'orderBy', {
value: function(sorts) {
sorts.map(sort => {
sort.uniques = Array.from(
new Set(this.map(obj => obj[sort.key]))
);
sort.uniques = sort.uniques.sort((a, b) => {
if (typeof a == 'string') {
return sort.inverse ? b.localeCompare(a) : a.localeCompare(b);
}
else if (typeof a == 'number') {
return sort.inverse ? (a < b) : (a > b ? 1 : 0);
}
else if (typeof a == 'boolean') {
let x = sort.inverse ? (a === b) ? 0 : a? -1 : 1 : (a === b) ? 0 : a? 1 : -1;
return x;
}
return 0;
});
});
const weightOfObject = (obj) => {
let weight = "";
sorts.map(sort => {
let zeropad = `${sort.uniques.length}`.length;
weight += sort.uniques.indexOf(obj[sort.key]).toString().padStart(zeropad, '0');
});
//obj.weight = weight; // if you need to see weights
return weight;
}
this.sort((a, b) => {
return weightOfObject(a).localeCompare( weightOfObject(b) );
});
return this;
}
});
使用:
// works with string, number and boolean
let sortered = your_array.orderBy([
{key: "type", inverse: false},
{key: "title", inverse: false},
{key: "spot", inverse: false},
{key: "internal", inverse: true}
]);
答案 9 :(得分:1)
这是一个使用递归对从1到无限的任意数量的排序字段进行排序的实现。您将结果数组(它是要排序的结果对象的数组)和结果数组(它是定义排序的排序对象的数组)传递给它。每个排序对象必须具有用于排序的键名称的“选择”键和“顺序”键,该键是指示“升序”或“降序”的字符串。
sortMultiCompare = (a, b, sorts) => {
let select = sorts[0].select
let order = sorts[0].order
if (a[select] < b[select]) {
return order == 'ascending' ? -1 : 1
}
if (a[select] > b[select]) {
return order == 'ascending' ? 1 : -1
}
if(sorts.length > 1) {
let remainingSorts = sorts.slice(1)
return this.sortMultiCompare(a, b, remainingSorts)
}
return 0
}
sortResults = (results, sorts) => {
return results.sort((a, b) => {
return this.sortMultiCompare(a, b, sorts)
})
}
// example inputs
const results = [
{
"LastName": "Doe",
"FirstName": "John",
"MiddleName": "Bill"
},
{
"LastName": "Doe",
"FirstName": "Jane",
"MiddleName": "Bill"
},
{
"LastName": "Johnson",
"FirstName": "Kevin",
"MiddleName": "Bill"
}
]
const sorts = [
{
"select": "LastName",
"order": "ascending"
},
{
"select": "FirstName",
"order": "ascending"
},
{
"select": "MiddleName",
"order": "ascending"
}
]
// call the function like this:
let sortedResults = sortResults(results, sorts)
答案 10 :(得分:1)
让我们简化。
假设你有一个数组:
let tmp = [
[0, 1],
[2, 1],
[1, 1],
[0, 0],
[2, 0],
[1, 0],
[0, 2],
[2, 2],
[1, 2],
]
执行:
tmp.sort((a, b) => {
if (a[1] != b[1])
return a[1] - b[1];
else
return a[0] - b[0];
})
将产生:
[
[0, 0],
[1, 0],
[2, 0],
[0, 1],
[1, 1],
[2, 1],
[0, 2],
[1, 2],
[2, 2]
]
答案 11 :(得分:0)
这就是我使用的
function sort(a, b) {
var _a = "".concat(a.size, a.glow);
var _b = "".concat(b.size, b.glow);
return _a < _b;
}
将两个项目作为字符串连接起来,它们将按字符串值排序。如果你想要,你可以用parseInt包装_a和_b,将它们作为数字进行比较,如果你知道它们是数字的。
答案 12 :(得分:0)
grouperArray.sort(
function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize}
);
答案 13 :(得分:0)
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
if (aSize !== aSize)
return aSize - bSize;
return a.glow - b.glow;
});
未经测试,但我认为应该可行。
答案 14 :(得分:0)
当您拥有优先级排序键(某些特定项目中可能不存在)时,这里是解决方案,因此您必须按后备键进行排序。
输入数据示例( id2 是优先级排序键):
const arr = [
{id: 1},
{id: 2, id2: 3},
{id: 4},
{id: 3},
{id: 10, id2: 2},
{id: 7},
{id: 6, id2: 1},
{id: 5},
{id: 9, id2: 2},
{id: 8},
];
输出应为:
[ { id: 6, id2: 1 },
{ id: 9, id2: 2 },
{ id: 10, id2: 2 },
{ id: 2, id2: 3 },
{ id: 1 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 7 },
{ id: 8 } ]
比较器功能将类似于:
arr.sort((a,b) => {
if(a.id2 || b.id2) {
if(a.id2 && b.id2) {
if(a.id2 === b.id2) {
return a.id - b.id;
}
return a.id2 - b.id2;
}
return a.id2 ? -1 : 1;
}
return a.id - b.id
});
P.S。如果 .id2 中的 .id 可以为零,请考虑使用typeof
。
答案 15 :(得分:0)
就我而言,我按参数“重要”和“日期”对通知列表进行排序
步骤1:我按“重要”和“不重要”过滤通知
let importantNotifications = notifications.filter(
(notification) => notification.isImportant);
let unImportantNotifications = notifications.filter(
(notification) => !notification.isImportant);
步骤2:我按日期对它们进行排序
sortByDate = (notifications) => {
return notifications.sort((notificationOne, notificationTwo) => {
return notificationOne.date - notificationTwo.date;
});
};
第3步:合并它们
[
...this.sortByDate(importantNotifications),
...this.sortByDate(unImportantNotifications),
];
答案 16 :(得分:0)
如果您乐于使用新的 tidy.js package,您可以使用
tidy(input_array,
arrange(['var1', desc('var2')])
);