Search code examples
javascripttypescriptvue.jssorting

Sorting a object's properties after reducing


I am recreating the effects of an outlook mailbox by grouping a list of outlook emails by their conversation id. However, I need to sort my list twice such that the emails in each group are ordered from newest email to oldest and also the conversation list itself needs to be sorted oldest to newest. Since the conversations are arrays it would need to use the first item in the array (which should be the newest of that array once sorted) to make this array comparison then.

The object looks like this once grouped:

{"sdfjskldfjks" : [{from: "joe", received_date:"07/11/1990 5:30PM"}], "dfjsakldfjhsa" : [{from: "john", received_date:"07/12/1990 5:30PM"},{from: "jake", received_date:"07/12/1989 5:30PM"}]}

My function I am using to do this grouping is as follows:

  const cleanFolder = computed(() => {
    if(currentFolder.value == null){
      return []
    }
  
    function groupBy(arr: any[], property: string) {
        return arr.reduce(function (memo: { [x: string]: any[]; }, x: { [x: string]: string | number; }) {
            if (!memo[x[property]]) { memo[x[property]] = []; }
            memo[x[property]].push(x);
            return memo;
        }, {});
    };

    return groupBy(currentFolder.value.emails,'conversation_id')
  })

I am aware how to sort an array but I need to sort based on a object as shown so I am clueless!


Solution

  • Firstly, You need to group emails by conversation_id. Then Sort each conversation group by received_date. After that, you need to sort conversations by groups from the received_date of the newest email in each group. Refer to the order in cleanFolder().

    Refer the code below for more reference:

    const emails = [
        { from: 'joe', received_date: '07/11/1990 5:30PM', conversation_id: 'sdfjskldfjks' },
        { from: 'john', received_date: '07/12/1990 5:30PM', conversation_id: 'dfjsakldfjhsa' },
        { from: 'jake', received_date: '07/12/1989 5:30PM', conversation_id: 'dfjsakldfjhsa' }
    ];
    
    function groupBy(arr, property) {
        return arr.reduce(function (memo, email) {
            if (!memo[email[property]]) { 
                memo[email[property]] = []; 
            }
            memo[email[property]].push(email);
            return memo;
        }, {});
    }
    
    function sortEmailsByDateDescending(emails) {
        return emails.sort((a, b) => new Date(b.received_date) - new Date(a.received_date));
    }
    
    function sortConversationGroupsByNewestEmailDate(conversationGroups) {
        return conversationGroups.sort((groupA, groupB) => {
            const newestA = new Date(groupA[0].received_date);
            const newestB = new Date(groupB[0].received_date);
            return newestA - newestB;
        });
    }
    
    function cleanFolder() {
        if (emails.length === 0) {
            return [];
        }
        const groupedEmails = groupBy(emails, 'conversation_id'); // group from conversation_id
        let conversationGroups = Object.values(groupedEmails);
        conversationGroups = conversationGroups.map(sortEmailsByDateDescending);
        conversationGroups = sortConversationGroupsByNewestEmailDate(conversationGroups);
    
        return conversationGroups;
    }
    
    console.log(JSON.stringify(cleanFolder()));