我觉得可能有更好的解决方案,因为我在下面的例程中重复了代码(map和sort)。
它是具有read(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},
];
答案 0 :(得分: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}
];
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);
&#13;
<强>更新强>
要处理null
字段的Read
值(反直觉地)被视为 truthy 这一事实,您必须引入几个临时变量(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);
&#13;
答案 1 :(得分: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);
答案 2 :(得分:0)
您可以先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);
&#13;