过滤,映射,排序和连接

时间:2017-04-25 23:48:25

标签: javascript sorting filter concat

我觉得可能有更好的解决方案,因为我在下面的例程中重复了代码(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},
];

3 个答案:

答案 0 :(得分:1)

好像你只想对多个字段进行排序。要先按读取状态排序,然后按姓氏排序,再按名字排序(忽略大小写),您可以:

&#13;
&#13;
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;
&#13;
&#13;

<强>更新

要处理null字段的Read值(反直觉地)被视为 truthy 这一事实,您必须引入几个临时变量(let aRead = a.Read != null a.Read : 1)并比较这些变量,或重写比较如下:

&#13;
&#13;
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;
&#13;
&#13;

答案 1 :(得分:0)

只需将您的mapsort函数移动到自己的命名函数中并重复使用它们:

// 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累积结果:

&#13;
&#13;
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;
&#13;
&#13;