简体   繁体   中英

JavaScript Sort Function with more than one criteria

Here is a sample of what I am sorting:

[
  ['Zed Jones', '24 Nov 2017 2:00 PM'],
  ['Jack Mo', '25 Nov 2017 5:00 PM'],
  ['John Phil', '25 Nov 2017 4:00 PM'],
  ['Bob Phil', '25 Nov 2017 4:00 PM']
]

Here is my desired output:

[
  ['Zed Jones', '24 Nov 2017 2:00 PM'],
  ['Bob Phil', '25 Nov 2017 4:00 PM'],
  ['John Phil', '25 Nov 2017 4:00 PM'],
  ['Jack Mo', '25 Nov 2017 5:00 PM']
]

Notice how the output is sorted by day, hour, and first letter of first name

Here is my code below. I have been able to sort by day and hour pretty easily but I am having trouble finding a way to compare and place first letter of first name:

function sortTable(data) {
  return data.sort((elem1, elem2) => {
    var dateA      = new Date(elem1[1])
      , dateB      = new Date(elem2[1])

    return dateA.getHours() - dateB.getHours() + dateB.setHours(0) - dateA.setHours(0);
  });
}

I have tried to sort once by date and then perform another sort function comparing the first letter of each first name, but I am having issues as it does not properly sort the data:

function sortTable(data) {
  // Sort by date and time
  data = data.sort((elem1, elem2) => {
    var dateA      = new Date(elem1[1])
      , dateB      = new Date(elem2[1])

    return dateA.getHours() - dateB.getHours() + dateB.setHours(0) - dateA.setHours(0);
  });

  // Then sort by name and return data
  return data.sort((elem1, elem2) => {
    var name1 = elem1[0]
      , name2 = elem2[0]
      , let1
      , let2;

    // Check that we have a name available
    if (name1 !== undefined) let1 = name1.charAt(0);
    if (name2 !== undefined) let2 = name2.charAt(0);

      return let1 < let2;
  });
 }

In what ways can I modify this code to achieve my desired output? Any help would be greatly appreciated. Thank you in advance!

You could take the delta of the second element as date difference and take the first character for sorting if the delta is zero of the date

 var data = [['Zed Jones', '24 Nov 2017 2:00 PM'], ['Jack Mo', '25 Nov 2017 5:00 PM'], ['John Phil', '25 Nov 2017 4:00 PM'], ['Bob Phil', '25 Nov 2017 4:00 PM']]; data.sort(function (a, b) { return new Date(a[1]) - new Date(b[1]) || a[0][0] > b[0][0] || -(a[0][0] < b[0][0]); }); console.log(data); 

We should check the date-diff and only if it's zero - we'll sort by the first character, see code-comments:

 var data = [ ['Zed Jones', '24 Nov 2017 2:00 PM'], ['Jack Mo', '25 Nov 2017 5:00 PM'], ['John Phil', '25 Nov 2017 4:00 PM'], ['Bob Phil', '25 Nov 2017 4:00 PM'] ]; function sortTable(data) { // Then sort by name and return data return data.sort((elem1, elem2) => { var dateA = new Date(elem1[1]) , dateB = new Date(elem2[1]); var name1 = elem1[0] , name2 = elem2[0] , let1 , let2; var dateDiff = dateA - dateB; // compare dates first // if we have a date-difference we'll use it if (dateDiff !== 0) { return dateDiff; } // only if no date-diff - compare names! if (name1 !== undefined) let1 = name1.charAt(0); if (name2 !== undefined) let2 = name2.charAt(0); return let1 > let2; // change the comparison from < to > }); } sortTable(data); console.log(data) 

You can use String.prototype.localeCompare

 var input = [['Zed Jones', '24 Nov 2017 2:00 PM'], ['Jack Mo', '25 Nov 2017 5:00 PM'], ['John Phil', '25 Nov 2017 4:00 PM'], ['Bob Phil', '25 Nov 2017 4:00 PM'], ['Bob Phil', '01 Dec 2017 01:00 AM'], ['1Bob Phil', '01 Dec 2017 01:00 AM'], ['asdf df', '01 Dec 1999 01:30 PM']]; //Now with the help of `localeCompare` function sortTable(data) { return data.sort((elem1, elem2) => { var dateA = new Date(elem1[1]) , dateB = new Date(elem2[1]) , nameA = elem1[0] , nameB = elem2[0] , datecomp = dateA - dateB , namecomp = nameA.localeCompare(nameB); return datecomp > 0 ? datecomp : datecomp + namecomp; }); } //See results:- sortTable(input); console.log(input); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM