soni
soni

Reputation: 739

Sort an array of objects by different keys

Hope you can help me with this question I have, that I'm pretty sure it's simple but I feel I'm missing some basic concepts here.

I have an array of objects like

[{
  "id":"123",
  "creationUser":"user1",
  "updateUser":null,
  "creationDate":1517495569000,
  "updateDate":null,
  "text":"Hello World"
},

{
  "id":"543",
  "creationUser":"user2",
  "updateUser":"user3",
  "creationDate":1517912985769,
  "updateDate":1517921704448,
  "text":"Hello people"
},

{
  "id":"847",
  "creationUser":"user 4",
  "updateUser":null,
  "creationDate":null,
  "updateDate":1517913015110,
  "text":"Text 1"
},

{
  "id":"344",
  "creationUser":"user 1",
  "updateUser":"central",
  "creationDate":1517912979283,
  "updateDate":1517923926834,
  "text":"Aloha!"
}]

As you can see there are some objects that doesn't have been updated so those values are set to null, but others have been updated, so what I would like to do is to order that array by creation date unless it has been updated, which mean that the updatedDate is the key value to compare this array.

I have tried:

let comments = conversation.sort(
   (a,b) => {
      if (a.updateDate){
         return (a.creationDate - b.updateDate);
      } else {
        return (b.creationDate - a.updateDate);
      }
});

But obviously it only works when comparing non updated objects. I'm pretty sure I'm missing something but I'm not sure, I also thought on splitting the array into updated array and non updated array and then merege it, but it sounds a bit hacky to me.

Please please, if you can give me a hint on this, it would be great!

Thanks a lot!

Upvotes: 2

Views: 242

Answers (4)

Jonas Wilms
Jonas Wilms

Reputation: 138267

 ((a.updateDate || 0) - (b.updateDate || 0)) || a.creationDate - b.creationDate

That compares by creation date if both updateDates arent set, otherwise the updateSet comes first.

Upvotes: 0

Javier Gonzalez
Javier Gonzalez

Reputation: 1015

Evaluate the existence of the updateDate property first and if not exists, use the creationDate property:

var data =[{
  "id":"123",
  "creationUser":"user1",
  "updateUser":null,
  "creationDate":1517495569000,
  "updateDate":null,
  "text":"Hello World"
},

{
  "id":"543",
  "creationUser":"user2",
  "updateUser":"user3",
  "creationDate":1517912985769,
  "updateDate":1517921704448,
  "text":"Hello people"
},

{
  "id":"847",
  "creationUser":"user 4",
  "updateUser":null,
  "creationDate":null,
  "updateDate":1517913015110,
  "text":"Text 1"
},

{
  "id":"344",
  "creationUser":"user 1",
  "updateUser":"central",
  "creationDate":1517912979283,
  "updateDate":1517923926834,
  "text":"Aloha!"
}];

data.sort(function (a,b) {
   var aDate = a.updateDate?a.updateDate:a.creationDate;
   var bDate = b.updateDate?b.updateDate:b.creationDate;
   return aDate - bDate;
});
console.log(data)

Upvotes: 0

epascarello
epascarello

Reputation: 207511

So that make it so you use the defined dates by picking the one that is defined for each object.

  var aDate = a.updateDate || a.creationDate
  var bDate = b.updateDate || b.creationDate
  return bDate - aDate

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386604

You could use logical OR || and take as default creationDate.

var array = [{ id: "123", creationUser: "user1", updateUser: null, creationDate: 1517495569000, updateDate: null, text: "Hello World" }, { id: "543", creationUser: "user2", updateUser: "user3", creationDate: 1517912985769, updateDate: 1517921704448, text: "Hello people" }, { id: "847", creationUser: "user 4", updateUser: null, creationDate: null, updateDate: 1517913015110, text: "Text 1" }, { id: "344", creationUser: "user 1", updateUser: "central", creationDate: 1517912979283, updateDate: 1517923926834, text: "Aloha!" }];

array.sort((a, b) => (a.updateDate || a.creationDate) - (b.updateDate || b.creationDate));

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

Upvotes: 2

Related Questions