如何对 JavaScript 中的对象集合进行自然排序?
How to natural-sort a collection of objects in JavaScript?
Belong 是我的对象集合的一个示例。
const a = [
{name: "John", size: "100"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "110"},
{name: "John", size: "70"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XS"},
{name: "John", size: "L"},
{name: "John", size: "XL"},
]
以100大于80,100排在80之后为例,JavaScript如何自然排序?
挑战在于 size 的值是数字和字符串的混合。
期望的升序结果:
[
{name: "John", size: "70"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "100"},
{name: "John", size: "110"},
{name: "John", size: "L"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XL"},
{name: "John", size: "XS"},
]
降序所需结果:
[
{name: "John", size: "XS"},
{name: "John", size: "XL"},
{name: "John", size: "S"},
{name: "John", size: "M"},
{name: "John", size: "L"},
{name: "John", size: "110"},
{name: "John", size: "100"},
{name: "John", size: "82"},
{name: "John", size: "80"},
{name: "John", size: "70"},
]
我已经按升序尝试了 Lodash JavaScript 库,但它没有正确排序,因为它看到 100
小于 80
因为 100
以1
。
_.orderBy(a, ["size"], ["asc"])
您可以使用正常的 JavaScript 逻辑来实现。您可以显式创建一个尺寸映射,这将帮助您根据要求对值进行排序:
const a = [
{name: "John", size: "100"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "110"},
{name: "John", size: "70"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XS"},
{name: "John", size: "L"},
{name: "John", size: "XL"},
];
var sizes = {
'100': 3,
'80': 1,
'82': 2,
'110': 4,
'70': 0,
'M': 6,
'S': 7,
'XS': 9,
'L': 5,
'XL': 8,
}
//ascending
a.sort((x, y) => {
return sizes[x.size] - sizes[y.size];
});
console.log(a);
//descending
a.sort((x, y) => {
return sizes[y.size] - sizes[x.size];
});
console.log(a);
let array_data = [
{name: "John", size: "70"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "100"},
{name: "John", size: "110"},
{name: "John", size: "L"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XL"},
{name: "John", size: "XS"},
];
let sorted = array_data.sort((a, b) => {return parseInt(a.size) - parseInt(b.size);});
console.log(sorted);
正常排序 javascript 功能将起作用。
Ascending and Descending order
const arr = [{name: "John", size: "100"},{name: "John", size: "80"},{name: "John", size: "82"},{name: "John", size: "110"},{name: "John", size: "70"},{name: "John", size: "M"},{name: "John", size: "S"},{name: "John", size: "XS"},{name: "John", size: "L"},{name: "John", size: "XL"}],
handler = (a, b, desc) => {
if (isNaN(+a) && isNaN(+b)) return (desc ? b.localeCompare(a) : a.localeCompare(b));
else if (!isNaN(+a) && !isNaN(+b)) return (desc ? (+b - +a) : (+a - +b));
else if (isNaN(+a)) return (desc ? -1 : 1);
else return (desc ? 1 : -1);
},
descending = arr.sort(({size: a}, {size: b}) => handler(a, b, true)),
ascending = [...arr].sort(({size: a}, {size: b}) => handler(a, b));
console.log("Ascending")
console.log(ascending);
console.log("Descending")
console.log(descending);
.as-console-wrapper { max-height: 100% !important; top: 0; }
因为您已经在使用 loadsh。只需编写一个函数来评估 size 是 String 还是 Integer,然后它将为您排序。
对于desc,只需将asc数组反转即可。
const a = [ {name: "John", size: "100"}, {name: "John", size: "80"}, {name: "John", size: "82"}, {name: "John", size: "110"}, {name: "John", size: "70"}, {name: "John", size: "M"}, {name: "John", size: "S"}, {name: "John", size: "XS"}, {name: "John", size: "L"}, {name: "John", size: "XL"} ];
// ascednding
const b = _.orderBy(a, function(e) { return isNaN(e.size) ? e.size: parseInt(e.size)}, ["asc"]);
console.log("ASCENDING::");
console.log(b);
//descending
const c = _.reverse(b);
console.log("DESCENDING::");
console.log(c);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
const a = [
{name: "John", size: "100"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "110"},
{name: "John", size: "70"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XS"},
{name: "John", size: "L"},
{name: "John", size: "XL"},
]
// ascending
const sorted = arr => [...arr].sort((a, b) => a.size.localeCompare(b.size, 'en', {numeric: true}))
console.log(sorted(a))
Belong 是我的对象集合的一个示例。
const a = [
{name: "John", size: "100"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "110"},
{name: "John", size: "70"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XS"},
{name: "John", size: "L"},
{name: "John", size: "XL"},
]
以100大于80,100排在80之后为例,JavaScript如何自然排序?
挑战在于 size 的值是数字和字符串的混合。
期望的升序结果:
[
{name: "John", size: "70"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "100"},
{name: "John", size: "110"},
{name: "John", size: "L"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XL"},
{name: "John", size: "XS"},
]
降序所需结果:
[
{name: "John", size: "XS"},
{name: "John", size: "XL"},
{name: "John", size: "S"},
{name: "John", size: "M"},
{name: "John", size: "L"},
{name: "John", size: "110"},
{name: "John", size: "100"},
{name: "John", size: "82"},
{name: "John", size: "80"},
{name: "John", size: "70"},
]
我已经按升序尝试了 Lodash JavaScript 库,但它没有正确排序,因为它看到 100
小于 80
因为 100
以1
。
_.orderBy(a, ["size"], ["asc"])
您可以使用正常的 JavaScript 逻辑来实现。您可以显式创建一个尺寸映射,这将帮助您根据要求对值进行排序:
const a = [
{name: "John", size: "100"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "110"},
{name: "John", size: "70"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XS"},
{name: "John", size: "L"},
{name: "John", size: "XL"},
];
var sizes = {
'100': 3,
'80': 1,
'82': 2,
'110': 4,
'70': 0,
'M': 6,
'S': 7,
'XS': 9,
'L': 5,
'XL': 8,
}
//ascending
a.sort((x, y) => {
return sizes[x.size] - sizes[y.size];
});
console.log(a);
//descending
a.sort((x, y) => {
return sizes[y.size] - sizes[x.size];
});
console.log(a);
let array_data = [
{name: "John", size: "70"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "100"},
{name: "John", size: "110"},
{name: "John", size: "L"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XL"},
{name: "John", size: "XS"},
];
let sorted = array_data.sort((a, b) => {return parseInt(a.size) - parseInt(b.size);});
console.log(sorted);
正常排序 javascript 功能将起作用。
Ascending and Descending order
const arr = [{name: "John", size: "100"},{name: "John", size: "80"},{name: "John", size: "82"},{name: "John", size: "110"},{name: "John", size: "70"},{name: "John", size: "M"},{name: "John", size: "S"},{name: "John", size: "XS"},{name: "John", size: "L"},{name: "John", size: "XL"}],
handler = (a, b, desc) => {
if (isNaN(+a) && isNaN(+b)) return (desc ? b.localeCompare(a) : a.localeCompare(b));
else if (!isNaN(+a) && !isNaN(+b)) return (desc ? (+b - +a) : (+a - +b));
else if (isNaN(+a)) return (desc ? -1 : 1);
else return (desc ? 1 : -1);
},
descending = arr.sort(({size: a}, {size: b}) => handler(a, b, true)),
ascending = [...arr].sort(({size: a}, {size: b}) => handler(a, b));
console.log("Ascending")
console.log(ascending);
console.log("Descending")
console.log(descending);
.as-console-wrapper { max-height: 100% !important; top: 0; }
因为您已经在使用 loadsh。只需编写一个函数来评估 size 是 String 还是 Integer,然后它将为您排序。
对于desc,只需将asc数组反转即可。
const a = [ {name: "John", size: "100"}, {name: "John", size: "80"}, {name: "John", size: "82"}, {name: "John", size: "110"}, {name: "John", size: "70"}, {name: "John", size: "M"}, {name: "John", size: "S"}, {name: "John", size: "XS"}, {name: "John", size: "L"}, {name: "John", size: "XL"} ];
// ascednding
const b = _.orderBy(a, function(e) { return isNaN(e.size) ? e.size: parseInt(e.size)}, ["asc"]);
console.log("ASCENDING::");
console.log(b);
//descending
const c = _.reverse(b);
console.log("DESCENDING::");
console.log(c);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
const a = [
{name: "John", size: "100"},
{name: "John", size: "80"},
{name: "John", size: "82"},
{name: "John", size: "110"},
{name: "John", size: "70"},
{name: "John", size: "M"},
{name: "John", size: "S"},
{name: "John", size: "XS"},
{name: "John", size: "L"},
{name: "John", size: "XL"},
]
// ascending
const sorted = arr => [...arr].sort((a, b) => a.size.localeCompare(b.size, 'en', {numeric: true}))
console.log(sorted(a))