过滤、映射、排序和连接
filter, map, sort and concat
我觉得可能有更好的解决方案,因为我在以下例程(映射和排序)中有重复代码。
它是具有已读(1 或 null)和未读状态 (0) 的任意邮件列表。我在顶部显示未读消息,在底部显示已读消息并应用了一些排序和映射,然后在最后连接两个结果。
var unread = data.filter(function(item){
return item.Read == 0;
}).map(function(item){
return {Id: item.Id, First: item.First.toLowerCase(), Last: item.Last.toLowerCase()}
}).sort(function(a, b){
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
});
var read = data.filter(function(item){
return item.Read == null || item.Read == 1;
}).map(function(item){ // lowercase (first, last) and sort the list by last
return {Id: item.Id, First: item.First.toLowerCase(), Last: item.Last.toLowerCase()}
}).sort(function(a, b){
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
});
var finalData = unread.concat(read);
编辑
var input = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1},
{Id: 1, First: "Beta", Last: "C", Read:null},
];
var output = [
{Id: 1, First: "Alpha", Last: "B", Read:1},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Beta", Last: "C", Read: null},
{Id: 1, First: "John", Last: "B", Read:0}
{Id: 1, First: "Jane", Last: "C", Read:0},
];
只需将您的 map
和 sort
函数移动到它们自己的命名函数中并重新使用它们:
// helpers
function processItem(item) {
return {Id: item.Id, First: item.First.toLowerCase(), Last: item.Last.toLowerCase()}
}
function sortItemByLast(a, b) {
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
};
// process data
var unread = data.filter(function(item){
return item.Read == 0;
}).map(processItem).sort(sortItemByLast);
var read = data.filter(function(item){
return item.Read == null || item.Read == 1;
}).map(processItem).sort(sortItemByLast);
var finalData = unread.concat(read);
可以先sort
,再用reduce
累加结果:
var data = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1}
];
var result = data.sort(function(a, b){
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
}).reduce(function(res, o) {
var newO = {Id: o.Id, First: o.First.toLowerCase(), Last: o.Last.toLowerCase()}; // the object to be pushed to either the read or unread array (if you are not using the old object o, then just remove the property "Read" from it and use it without creating a new object)
res[o.Read == 0? "unread": "read"].push(newO); // push o to either the read or unread array, depending on the property "Read"
return res;
}, {read: [], unread: []}); // the initiale value will be an object containing two arrays (one for read and one for unread objects)
console.log(result);
您似乎只想对多个字段进行排序。要先按阅读状态排序,然后按姓氏排序,然后按名字排序(忽略大小写),您可以:
var data = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1}
];
data.sort((a, b) =>
b.Read !== a.Read
? b.Read - a.Read
: a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
? a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
: a.First.toLowerCase().localeCompare(b.First.toLowerCase()));
console.log(data);
更新
要处理 Read
字段的 null
值(违反直觉)被认为是 真实 的事实,您必须引入几个临时变量 (let aRead = a.Read != null a.Read : 1
) 并比较它们,或者重写比较如下:
var data = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1},
{Id: 1, First: "Beta", Last: "C", Read:null}
];
data.sort((a, b) =>
b.Read !== a.Read
? (b.Read != null ? b.Read : 1) - (a.Read != null ? a.Read : 1)
: a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
? a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
: a.First.toLowerCase().localeCompare(b.First.toLowerCase()));
console.log(data);
我觉得可能有更好的解决方案,因为我在以下例程(映射和排序)中有重复代码。
它是具有已读(1 或 null)和未读状态 (0) 的任意邮件列表。我在顶部显示未读消息,在底部显示已读消息并应用了一些排序和映射,然后在最后连接两个结果。
var unread = data.filter(function(item){
return item.Read == 0;
}).map(function(item){
return {Id: item.Id, First: item.First.toLowerCase(), Last: item.Last.toLowerCase()}
}).sort(function(a, b){
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
});
var read = data.filter(function(item){
return item.Read == null || item.Read == 1;
}).map(function(item){ // lowercase (first, last) and sort the list by last
return {Id: item.Id, First: item.First.toLowerCase(), Last: item.Last.toLowerCase()}
}).sort(function(a, b){
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
});
var finalData = unread.concat(read);
编辑
var input = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1},
{Id: 1, First: "Beta", Last: "C", Read:null},
];
var output = [
{Id: 1, First: "Alpha", Last: "B", Read:1},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Beta", Last: "C", Read: null},
{Id: 1, First: "John", Last: "B", Read:0}
{Id: 1, First: "Jane", Last: "C", Read:0},
];
只需将您的 map
和 sort
函数移动到它们自己的命名函数中并重新使用它们:
// helpers
function processItem(item) {
return {Id: item.Id, First: item.First.toLowerCase(), Last: item.Last.toLowerCase()}
}
function sortItemByLast(a, b) {
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
};
// process data
var unread = data.filter(function(item){
return item.Read == 0;
}).map(processItem).sort(sortItemByLast);
var read = data.filter(function(item){
return item.Read == null || item.Read == 1;
}).map(processItem).sort(sortItemByLast);
var finalData = unread.concat(read);
可以先sort
,再用reduce
累加结果:
var data = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1}
];
var result = data.sort(function(a, b){
if (a.Last < b.Last) return -1;
if (a.Last > b.Last) return 1;
return 0;
}).reduce(function(res, o) {
var newO = {Id: o.Id, First: o.First.toLowerCase(), Last: o.Last.toLowerCase()}; // the object to be pushed to either the read or unread array (if you are not using the old object o, then just remove the property "Read" from it and use it without creating a new object)
res[o.Read == 0? "unread": "read"].push(newO); // push o to either the read or unread array, depending on the property "Read"
return res;
}, {read: [], unread: []}); // the initiale value will be an object containing two arrays (one for read and one for unread objects)
console.log(result);
您似乎只想对多个字段进行排序。要先按阅读状态排序,然后按姓氏排序,然后按名字排序(忽略大小写),您可以:
var data = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1}
];
data.sort((a, b) =>
b.Read !== a.Read
? b.Read - a.Read
: a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
? a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
: a.First.toLowerCase().localeCompare(b.First.toLowerCase()));
console.log(data);
更新
要处理 Read
字段的 null
值(违反直觉)被认为是 真实 的事实,您必须引入几个临时变量 (let aRead = a.Read != null a.Read : 1
) 并比较它们,或者重写比较如下:
var data = [
{Id: 1, First: "John", Last: "B", Read:0},
{Id: 1, First: "Jane", Last: "C", Read:0},
{Id: 1, First: "Doe", Last: "D", Read:1},
{Id: 1, First: "Alpha", Last: "B", Read:1},
{Id: 1, First: "Beta", Last: "C", Read:null}
];
data.sort((a, b) =>
b.Read !== a.Read
? (b.Read != null ? b.Read : 1) - (a.Read != null ? a.Read : 1)
: a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
? a.Last.toLowerCase().localeCompare(b.Last.toLowerCase())
: a.First.toLowerCase().localeCompare(b.First.toLowerCase()));
console.log(data);