問題描述
如何在 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"},
]
我如何在 JavaScript 中以自然的方式對 100 大於 80 以及 100 位於 80 之後的示例進行排序?
p>挑戰在於 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"},
]
降序的期望結果:
p>[
{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"])
參考解法
方法 1:
As you are using loadsh already. Simply write a function that evaluates if size is String or Integer and then it will sort asc for you.
for desc, you can just reverse the asc array.
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>
方法 2:
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; }
方法 3:
<div class="snippet" data‑lang="js" data‑hide="false" data‑console="true" data‑babel="false">
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))
方法 4:
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);
Normal sort javascript function will be work.
(by O Connor、Bilal Siddiqui、Ele、pank、sourav satyam)