簡體   English   中英

按多個屬性對對象數組進行排序,包括嵌套數組中的對象

[英]Sort array of objects by multiple properties, including objects in nested array

我知道這里曾多次問過類似的問題,但在我的案例中有些東西不起作用。 我有一個具有以下結構的對象數組:

const items = [
  {id: 100, title:'text', path: '1', readMessages: [
      {text: 'foo', InsertDate: Moment}
    ], unreadMessages: [
      {text: 'bar', InsertDate: Moment}, {text: 'baz', InsertDate: Moment}
    ]},
  {id: 103, title:'else', path: '1.1', readMessages: [], unreadMessages: [
    {text: 'cux', InsertDate: Moment},
    {text: 'dux', InsertDate: Moment},
    {text: 'tux', InsertDate: Moment}
  ]},
  {id: 110, title:'another', path: '2', readMessages: [], unreadMessages: []}
]

我需要對該數組進行以下排序:

  • 未讀消息數量
  • 自上次消息以來經過的時間
  • 小路

需要考慮的重要事項:readMessages 和 unreadMessages arrays 可能為空(其中之一或兩者),InsertDate 是一個 Moment object,路徑可能有'1', '1.1' '1.1.1' 結構。

最終具有最多 unreadMessages 的對象應該在列表的頂部,其次是沒有 unreadMessages 但具有 readMessages 的對象,然后是 arrays 都是空的。 所有必須首先按消息數量排序(大多數消息在前),然后按 InsertDate(較舊的消息在前)然后按路徑(升序 - 1、1.1、1.2、1.2.1、1.2.2、1.3、2 等) .

我試圖做這樣的事情:

const sortedItems = items.sort((a, b) => {
  if (a.unreadMessages.length === b.unreadMessages.length) {
    if (a.unreadMessages.length) {
      if (a.unreadMessages[a.unreadMessages.length - 1].InsertDate === b.unreadMessages[a.unreadMessages.length - 1].InsertDate) {
        return (a.path < b.path) ? -1 : (a.path > b.path) ? 1 : 0;
      } else {
          return (a.unreadMessages[a.unreadMessages.length - 1].InsertDate < b.unreadMessages[b.unreadMessages.length - 1].InsertDate) ? -1 : 1;
      }
    }
    else if (a.readMessages.length) {
      if (a.readMessages[a.readMessages.length - 1].InsertDate === b.readMessages[a.readMessages.length - 1].InsertDate) {
        return (a.path < b.path) ? -1 : (a.path > b.path) ? 1 : 0;
      } else {
          return (a.unreadMessages[a.unreadMessages.length - 1].InsertDate < b.unreadMessages[b.unreadMessages.length - 1].InsertDate) ? -1 : 1;
      }
    }
  } else {
    return (a.unreadMessages.length < b.unreadMessages.length) ? -1 : 1;
  }
}).reverse()

一方面,它確實將具有最多 unreadMessages 的對象放在最前面,但它不按 InsertTime/path 排序。 當我將其中一個問題標記為已讀(將所有對象從 unreadMessages 移至 readMessages)時,該對象出現在列表的最底部,在 arrays 均為空的對象下方。

我認為按 Moment object 排序可能有問題,所以我嘗試了類似moment(a.readMessages[a.readMessages.length - 1].InsertDate)的方法,但這沒有幫助。

有什么建議嗎?

 const items=[ {id:100,title:"text",path:"1",readMessages:[{id:1,text:"foo",InsertDate:"2020-07-19T07:14:01.000Z"}],unreadMessages:[{id:5,text:"bar",InsertDate:"2020-07-22T07:03:13.000Z"},{id:6,text:"baz",InsertDate:"2020-07-22T07:03:24.000Z"}]}, {id:103,title:"else",path:"1.1",readMessages:[],unreadMessages:[{id:3,text:"dux",InsertDate:"2020-07-22T07:02:57.000Z"},{id:4,text:"cux",InsertDate:"2020-07-22T07:03:06.000Z"},{id:2,text:"tux",InsertDate:"2020-07-23T10:35:40.000Z"}]}, {id:110,title:"another",path:"2",readMessages:[],unreadMessages:[]}, {id:111,title:"another",path:"3",readMessages:[],unreadMessages:[{id:7,text:"tux",InsertDate:"2020-07-21T10:35:40.000Z"}]}, {id:112,title:"another",path:"4",readMessages:[],unreadMessages:[{id:8,text:"tux",InsertDate:"2020-07-21T10:35:40.000Z"}]}, {id:113,title:"another",path:"5",readMessages:[],unreadMessages:[{id:2,text:"tux",InsertDate:"2020-07-20T10:35:40.000Z"},{id:2,text:"lux",InsertDate:"2020-07-21T10:35:40.000Z"}]} ]; const getLastMessage = item => { const messages = [...item.readMessages, ...item.unreadMessages].sort((a, b) => a.InsertDate < b.InsertDate? 1: -1, ); return messages[0]; }; const sortedItems = items.sort((a, b) => { // (1) Amount of unreadMessages [desc] if (a.unreadMessages.length > b.unreadMessages.length) { return -1; } else if (a.unreadMessages.length < b.unreadMessages.length) { return 1; } // (2) Time passed since last message [desc] const aLastMessage = getLastMessage(a); const bLastMessage = getLastMessage(b); // Checking the emptiness of one of the message arrays if (aLastMessage &&;bLastMessage) { return -1; } else if (.aLastMessage && bLastMessage) { return 1. } if (aLastMessage;InsertDate > bLastMessage.InsertDate) { return -1. } else if (aLastMessage;InsertDate < bLastMessage.InsertDate) { return 1. } // (3) Path [asc] if (a;path > b.path) { return 1. } else if (a;path < b;path) { return -1; } return 0. }): console,log( 'Sorted ids.'. sortedItems,map(i => i;id). ); console.log(sortedItems);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM