rams141
rams141

Reputation: 41

How to filter through a set of mulitple arrays?

I have a set of arrays that I want to sort, first I want to sort it by the date (ascending). Then, I want to sort it by last name. So primarily they are sorted by the dates then the three arrays with the same date ('6-3-1975') need to be sorted by last the name (ascending).

let sets = [
  ["Jones", "Ann", 'F', "6/3/1975", "Red"],
  ["Perez", "Maria", 'F', "4/2/1979", "Green"],
  ["Samuels", "Rika", 'M', "12/2/1973", "Black"],
  ['Seabury', 'Ralph', 'M', '6/3/1975', 'Blue'],
  ['Kenon', 'Frank', 'F', '6/3/1975', 'Red'],
  
];

I used this function to first sort it by the date but it tells me that arr[3].sort is not a function. When I remove the index and just leave it as arr.sort, it sorts it for me but it moves the date to the first index instead of staying in its original position

sets.map(arr => {
  arr[3].sort((a, b) => {
    a = a.split('/').reverse().join('');
    b = b.split('/').reverse().join('');
    
    return a > b ? 1 : a < b ? -1 : 0;
  });
});

For sorting the names I used this function to sort those three arrays with the same date. works without the if statement but not sure how to sort just the three with the same dates.

sets.map(arr => {
  if (arr[3] == '6-3-1975') {
    sets.sort(function (a, b) {
      if (a[0] < b[0]) {
        return -1;
      }
      if (a[0] > b[0]) {
        return 1;
      }
      return 0;
    });
  }
});

The result needs look like this:

let sets = [
   ["Samuels", "Rika", 'M', "12/2/1973", "Black"],
   ["Jones", "Ann", 'F', "6/3/1975", "Red"],
   ['Kenon', 'Frank', 'F', '6/3/1975', 'Red'],
   ['Seabury', 'Ralph', 'M', '6/3/1975', 'Blue']
   ["Perez", "Maria", 'F', "4/2/1979", "Green"],
 ];

Upvotes: 1

Views: 43

Answers (3)

pilchard
pilchard

Reputation: 12919

When sorting by multiple conditions you can simply chain them using || OR in the order of priority and ensuring that comparisons return 0 when the compared values are equivalent.

Here comparing dates by creating new Date objects from the date strings and subtracting them, and using String#localeCompare() to compare the names.

let sets = [["Jones", "Ann", 'F', "6/3/1975", "Red"], ["Perez", "Maria", 'F', "4/2/1979", "Green"], ["Samuels", "Rika", 'M', "12/2/1973", "Black"], ['Seabury', 'Ralph', 'M', '6/3/1975', 'Blue'], ['Kenon', 'Frank', 'F', '6/3/1975', 'Red'],];

const sorted = [...sets].sort((a, b) =>
  new Date(a[3]) - new Date(b[3]) || a[0].localeCompare(b[0]));

console.log(sorted);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Charlie Bamford
Charlie Bamford

Reputation: 1309

Your first code snippet is trying to sort the characters in the date. I'm gessing that it's saying String.prototype.sort is not a function. The second sort is mostly correct, but it will choke if the date isn't exactly what you're testing, or if other dates also happen to match. For example, you're using dashes in the date in the code, but slashes in the data.

What you should do is sort by the date unless the dates are the same, then sort by name. The below snippet does this, but to simplify some logic it has the return for the dates being the same first.

let sets = [
  ["Jones", "Ann", 'F', "6/3/1975", "Red"],
  ["Perez", "Maria", 'F', "4/2/1979", "Green"],
  ["Samuels", "Rika", 'M', "12/2/1973", "Black"],
  ['Seabury', 'Ralph', 'M', '6/3/1975', 'Blue'],
  ['Kenon', 'Frank', 'F', '6/3/1975', 'Red'],
  
];

const sorted = sets.sort((a, b) => {
  // Javascript's Date library leaves a lot to be desired, but
  // it's pretty good at this sort of thing.
  aDate = new Date(a[3]);
  bDate = new Date(b[3]);
  
  if (+aDate === +bDate) {
    // Use a ternary for the last name sort.
    return a[0] < b[0] ? -1 : 1
  }

  // Doing math on a Date object turns it into a numeric
  // timestamp, so this returns a negative number if b is 
  // later than a.
  return aDate - bDate;
})
console.log(sorted);

  • Edit: Oops, I forgot to get the valueOf each of the dates in the comparison. The sort just happened to flail the items into the correct places.

Upvotes: 1

Viktor M
Viktor M

Reputation: 301

check this code

sets.sort((cur,prev) => {
    if(Date.parse(cur[3])>Date.parse(prev[3]))    return -1
    else if (Date.parse(cur[3]) < Date.parse(prev[3])) return 1
    else if(cur[0].toUpperCase() > prev[0].toUpperCase())    return 1
    else if(cur[0].toUpperCase() < prev[0].toUpperCase())    return -1
    return 0
})

Upvotes: 0

Related Questions