-1

Well, I have an array objects with random values, Ex.

var value = [
    {"date":"06/11/2017","status":"B"},
    {"date":"06/11/2017","status":"B"},
    {"date":"15/05/2017","status":"R"},
    {"date":"15/05/2017","status":"R"},
    {"date":"14/05/2018","status":"R"},
    {"date":"05/05/2017","status":"R"},
    {"date":null,"status":"W"},
    {"date":null,"status":"W"},
    {"date":null,"status":"W"},
    {"date":"05/11/2017","status":"B"},
    {"date":"27/07/2017","status":"R"},
    {"date":"14/05/2018","status":"R"},
    {"date":"27/07/201","status":"R"},
    {"date":"14/05/2018","status":"R"},
    {"date":"26/02/2018","status":"R"},
    {"date":null,"status":"W"}
];

I wanted to sort this array firstly by key status & then by key date as,

Output:

var result =  [
    {"date":"05/11/2017","status":"B"}, 
    {"date":"06/11/2017","status":"B"},
    {"date":"06/11/2017","status":"B"},
    {"date":"05/05/2017","status":"R"},
    {"date":"15/05/2017","status":"R"},
    {"date":"15/05/2017","status":"R"},
    {"date":"27/07/2017","status":"R"},
    {"date":"14/05/2018","status":"R"},
    {"date":"14/05/2018","status":"R"},
    {"date":"14/05/2018","status":"R"},
    {"date":"26/02/2018","status":"R"},
    {"date":"27/07/2018","status":"R"},     
    {"date":null,"status":"W"},
    {"date":null,"status":"W"},
    {"date":null,"status":"W"},
    {"date":null,"status":"W"}
];

/*I tried few generic code to sort, */   
var result = value.sort(function (a, b) {
    var aValue = (a.date) ?  a.date: 0;
    var bValue = (b.date) ?  b.date: 0;
    return a.status - b.status ||  aValue - bValue;
});

I referred few examples SO Example but not getting expected output. Please suggest me best way to get this.

Salman A
  • 262,204
  • 82
  • 430
  • 521
Swapnil Yeole
  • 406
  • 3
  • 12
  • 26

5 Answers5

0

Would this work?

value = value.sort(function (a, b) {
  if (a === b || (a.status === b.status && a.date === b.date)) return 0;

  if (a.status > b.status) return 1;
  if (a.status < b.status) return -1;

  if (a.date > b.date) return 1;
  if (a.date < b.date) return -1;
})
Nsevens
  • 2,588
  • 1
  • 17
  • 34
0
return a.status - b.status ||  aValue - bValue;

The values you are dealing with are not numbers! You can't subtract one from the other.

Also: Don't use nested ternary operators. It makes it very hard to understand the code.

Use if statements. They are much more readable.

I think this is what you are looking for, but your description of the problem isn't clear. This should, however, show you the principles so you can tweak it as you want.

const a_is_first = -1;
const b_is_first = 1;

function compare(a, b) {
    // Sort and group by status first. Sort by date within the statuses.
    if (a.status < b.status) {
         return a_is_first;
    } else if (a.status > b.status) {
         return b_is_first;
    } else { // They are the same
         var a__date = convert_to_a_date_object(a.date);
         var b__date = convert_to_a_date_object(b.date);
         if (a__date < b__date) {
             return a_is_first;
         } else if (a__date > b__date) {
             return b_is_first;
         } else {
             return 0;
         }
    }
}

value.sort(compare);

The implementation of convert_to_a_date_object is left as an exercise for the reader. Remember it has to handle null.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

Please see if this helps

value.sort(function(a, b) {
  var nameA = a.status.toUpperCase(),
    nameB = b.status.toUpperCase();
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
}).sort(function(a, b) {
  return new Date(b.date) - new Date(a.date);
});
Sunil Hari
  • 1,716
  • 1
  • 12
  • 20
0

Your date is under format "dd/mm/yyyy". You can use Date.parse("11/05/2017") (with format "mm/dd/yyyy", see parse for more formats) to return the number of milliseconds and compare. For the status, you can use status.charCodeAt(0) to get ASCII value and compare. Assuming that you have a good date format, here is the solution:

value.sort(function(a, b) {
  var diff = Date.parse(a.date) - Date.parse(b.date);
  if (diff === 0) {
    return a.status.charCodeAt(0) - b.status.charCodeAt(0);
  } 
  return diff;
});

Hope it helps.

Quan VO
  • 1,258
  • 11
  • 19
0

You could take status for sorting and if equal take a date string in ISO 8601 notation for sorting. ISO 6801 allowes to use a sorting by string without taking a date object.

var array = [{ date: "06/11/2017", status: "B" }, { date: "06/11/2017", status: "B" }, { date: "15/05/2017", status: "R" }, { date: "15/05/2017", status: "R" }, { date: "14/05/2018", status: "R" }, { date: "05/05/2017", status: "R" }, { date: null, status: "W" }, { date: null, status: "W" }, { date: null, status: "W" }, { date: "05/11/2017", status: "B" }, { date: "27/07/2017", status: "R" }, { date: "14/05/2018", status: "R" }, { date: "27/07/2017", status: "R" }, { date: "14/05/2018", status: "R" }, { date: "26/02/2018", status: "R" }, { date: null, status: "W" }];

array.sort(function (a, b) {
    function getDate(d) {
        return d ? d.replace(/(..)\/(..)\/(....)/, '$3-$2-$1') : '';
    }

    return a.status.localeCompare(b.status) || getDate(a.date).localeCompare(getDate(b.date));
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392