首先,我们可以获取您开始使用的数据并创建一个新的对象数组,在其中我们将每个人映射到他们指定的年龄,然后我们按其age 属性值对该对象数组进行排序:
let users = {
name: ["joe", "tim", "bob", "joe"],
age: [23, 22, 21, 20]
};
const associateUserDetails = users => Array(users.name.length).fill().map((e,i) => ({name: users.name[i], age: users.age[i]})).sort((a,b) => a.age - b.age);
console.log(associateUserDetails(users));
/* -> [
{ name: "joe", age: 20 },
{ name: "bob", age: 21 },
{ name: "tim", age: 22 },
{ name: "joe", age: 23 }
]
*/
一旦我们按年龄对这个用户数组进行排序,剩下要做的就是将对象数组拆分为 name 和 age 的两个嵌套数组,如下所示:
let users = {
name: ["joe", "tim", "bob", "joe"],
age: [23, 22, 21, 20]
};
const associateUserDetails = users => Array(users.name.length).fill().map((e,i) => ({name: users.name[i], age: users.age[i]})).sort((a,b) => a.age - b.age);
const splitByDetail = users => users.flatMap(user => Object.entries(user)).reduce((a,c) => (a[c[0]] ? a[c[0]].push(c[1]) : a[c[0]] = [c[1]], a), {});
console.log(splitByDetail(associateUserDetails(users)));
/* -> {
name: ["joe", "bob", "tim", "joe"],
age: [20, 21, 22, 23]
}
*/
现在让我们把这一切结合起来:
let users = {
name: ["joe", "tim", "bob", "joe"],
age: [23, 22, 21, 20]
};
const sortUsersByAge = users => Array(users.name.length).fill().map((e,i) => ({name: users.name[i], age: users.age[i]})).sort((a,b) => a.age - b.age).flatMap(user => Object.entries(user)).reduce((a,c) => (a[c[0]] ? a[c[0]].push(c[1]) : a[c[0]] = [c[1]], a), {});
console.log(sortUsersByAge(users));
/* -> {
name: ["joe", "bob", "tim", "joe"],
age: [20, 21, 22, 23]
}
*/
奖金
现在有一个奖励 - 假设您有一个像您提供的对象一样的对象......
- 正在处理更多用户详细信息,甚至可能是可变数量的详细信息,您宁愿明确列出它们
- 希望能够按列出的任何用户详细信息、姓名(字母排序)、年龄(数字排序)、ID 号(数字排序)或其他一些属性(默认为字母排序,除非所有值都是数字)
- 希望添加一个布尔值 true/false 开关,以快速反转任何排序函数的顺序,例如
sortUsers(users, true),其中第二个参数将在排序后反转每个最终数组的状态
- 您想将此函数用作
Object.prototype 方法,例如users.sortBy('age') 而不是sortObject(users, 'age')
让我们进行所有这些改进,并将它们整合到一个原型函数Object.sortBy():
let users = {
name: ["joe", "tim", "bob", "joe"],
age: [23, 22, 21, 20],
color: ["blue", "green", "red", "yellow"]
};
Object.prototype.sortBy = function(sortBy, descending = false) { return sortBy && Object.keys(this).includes(sortBy) ? [Array(this[Object.keys(this)[0]].length).fill().map((e,i) => Object.fromEntries(Object.keys(this).map(key => [key, this[key][i]])))].map(obj => obj.sort((a,b) => obj.every(user => typeof user[sortBy] === "number") ? a[sortBy] - b[sortBy] : (a[sortBy] > b[sortBy] ? 1 : -1)))[0].flatMap(user => Object.entries(user)).reduce((a,c) => (a[c[0]] ? a[c[0]].push(c[1]) : a[c[0]] = [c[1]], a), {}) : this };
users.sortBy('age');
/* -> {
name: ["joe", "bob", "tim", "joe"],
age: [20, 21, 22, 23],
color: ["yellow", "red", "green", "blue"]
}
*/
users.sortBy('name');
/* -> {
name: ["bob", "joe", "joe", "tim"],
age: [21, 20, 23, 22],
color: ["red", "yellow", "blue", "green"]
}
*/
users.sortBy('color', true); // true here will sort colors by name in descending order
/* -> {
name: ["joe", "bob", "tim", "joe"],
age: [20, 21, 22, 23],
color: ["yellow", "red", "green", "blue"]
}
*/