对具有空属性的对象进行排序会在 Firefox 和 Chrome 之间产生不同的结果
Sorting an object with null properties yields different results between Firefox and Chrome
我有一个对象数组,我正尝试对其应用 2 种排序。对 'name' 属性 进行简单的字母排序,然后对 'rank' 属性 进行排序,可以是数字或空值。具有 null 'rank' 的对象应排序到最终数组的末尾。
此代码在 Chrome、Safari 和 Edge 中按预期运行。然而,在 Firefox 中,它会颠倒所有具有空 'rank'.
的对象的字母顺序
JSFiddle:https://jsfiddle.net/6Lfu1z39/
代码:
const data = [
{
"name": "F",
"rank": 2
},{
"name": "B",
"rank": null
},{
"name": "A",
"rank": 1
},{
"name": "E",
"rank": null
},{
"name": "D",
"rank": null
},{
"name": "C",
"rank": 2
}
]
const nameSort = (a, b) => {
const nameA = a.name.toUpperCase();
const nameB = b.name.toUpperCase();
if (nameA < nameB) {
return -1;
} else if (nameA > nameB) {
return 1;
}
return 0;
};
const rankSort = (a, b) => {
if (a.rank === null) {
return 1;
} else if (b.rank === null) {
return -1;
}
return 0;
}
console.log('name only', data.sort(nameSort));
console.log('name and rank', data.sort(nameSort).sort(rankSort));
哪个浏览器是正确的?或者,是否可以采取任何措施使浏览器之间保持一致?
看起来,您 return 用于比较的相同值的错误值。
例如 a.rank === null
和 b.rank === null,你 return 1
但正确的值是在这种情况下,零到 return.
排序算法的实现取决于供应商,并且可以 return 不同的结果,具体取决于排序的顺序,例如从开始还是从结束。
要克服这个问题,您需要实现一个算法,该算法return对于相等的值为零。
const data = [{ name: "F", rank: 2 }, { name: "B", rank: null }, { name: "A", rank: 1 }, { name: "E", rank: null }, { name: "D", rank: null }, { name: "C", rank: 2 }]
const nameSort = (a, b) => {
const nameA = a.name.toUpperCase();
const nameB = b.name.toUpperCase();
return nameA > nameB || -(nameA < nameB);
};
const rankSort = (a, b) => (a.rank === null) - (b.rank === null)
console.log('name only', data.sort(nameSort));
console.log('name and rank', data.sort(nameSort).sort(rankSort));
.as-console-wrapper { max-height: 100% !important; top: 0; }
这是解决此问题的另一种方法。您可以结合使用 Array.prototype.sort()
和 Array.prototype.filter()
方法来获得最终结果。首先,对名称 属性 应用字母排序。之后使用数组过滤的方法将所有的空 'rank' 属性 放在数组的末尾。
const data = [
{
name: 'F',
rank: 2,
},
{
name: 'B',
rank: null,
},
{
name: 'A',
rank: 1,
},
{
name: 'E',
rank: null,
},
{
name: 'D',
rank: null,
},
{
name: 'C',
rank: 2,
},
];
data.sort((x, y) => x.name.localeCompare(y.name));
console.log('name only', data);
const ret = [
...data.filter((x) => x.rank !== null),
...data.filter((x) => x.rank === null),
];
console.log('name and rank', ret);
我有一个对象数组,我正尝试对其应用 2 种排序。对 'name' 属性 进行简单的字母排序,然后对 'rank' 属性 进行排序,可以是数字或空值。具有 null 'rank' 的对象应排序到最终数组的末尾。
此代码在 Chrome、Safari 和 Edge 中按预期运行。然而,在 Firefox 中,它会颠倒所有具有空 'rank'.
的对象的字母顺序JSFiddle:https://jsfiddle.net/6Lfu1z39/
代码:
const data = [
{
"name": "F",
"rank": 2
},{
"name": "B",
"rank": null
},{
"name": "A",
"rank": 1
},{
"name": "E",
"rank": null
},{
"name": "D",
"rank": null
},{
"name": "C",
"rank": 2
}
]
const nameSort = (a, b) => {
const nameA = a.name.toUpperCase();
const nameB = b.name.toUpperCase();
if (nameA < nameB) {
return -1;
} else if (nameA > nameB) {
return 1;
}
return 0;
};
const rankSort = (a, b) => {
if (a.rank === null) {
return 1;
} else if (b.rank === null) {
return -1;
}
return 0;
}
console.log('name only', data.sort(nameSort));
console.log('name and rank', data.sort(nameSort).sort(rankSort));
哪个浏览器是正确的?或者,是否可以采取任何措施使浏览器之间保持一致?
看起来,您 return 用于比较的相同值的错误值。
例如 a.rank === null
和 b.rank === null,你 return 1
但正确的值是在这种情况下,零到 return.
排序算法的实现取决于供应商,并且可以 return 不同的结果,具体取决于排序的顺序,例如从开始还是从结束。
要克服这个问题,您需要实现一个算法,该算法return对于相等的值为零。
const data = [{ name: "F", rank: 2 }, { name: "B", rank: null }, { name: "A", rank: 1 }, { name: "E", rank: null }, { name: "D", rank: null }, { name: "C", rank: 2 }]
const nameSort = (a, b) => {
const nameA = a.name.toUpperCase();
const nameB = b.name.toUpperCase();
return nameA > nameB || -(nameA < nameB);
};
const rankSort = (a, b) => (a.rank === null) - (b.rank === null)
console.log('name only', data.sort(nameSort));
console.log('name and rank', data.sort(nameSort).sort(rankSort));
.as-console-wrapper { max-height: 100% !important; top: 0; }
这是解决此问题的另一种方法。您可以结合使用 Array.prototype.sort()
和 Array.prototype.filter()
方法来获得最终结果。首先,对名称 属性 应用字母排序。之后使用数组过滤的方法将所有的空 'rank' 属性 放在数组的末尾。
const data = [
{
name: 'F',
rank: 2,
},
{
name: 'B',
rank: null,
},
{
name: 'A',
rank: 1,
},
{
name: 'E',
rank: null,
},
{
name: 'D',
rank: null,
},
{
name: 'C',
rank: 2,
},
];
data.sort((x, y) => x.name.localeCompare(y.name));
console.log('name only', data);
const ret = [
...data.filter((x) => x.rank !== null),
...data.filter((x) => x.rank === null),
];
console.log('name and rank', ret);