0

My array object is like below example.

list = [
{'name': 'test1', 'email': 'test1@gmail.com', 'ispin': true, 'updatedAt': 1540456416646}
{'name': 'test2', 'email': 'test2@gmail.com', 'ispin': false, 'updatedAt': 1540456416111}
{'name': 'test3', 'email': 'test3@gmail.com', 'ispin': true, 'updatedAt': 1540456412541}
{'name': 'test4', 'email': 'test4@gmail.com', 'ispin': false, 'updatedAt': 1540456414521}
]

I'm able to sort this array object like this.

return conversationList.sort((a, b) => {
  const firstTimestamp = a.lastMessage && a.lastMessage.createdAt ? a.lastMessage.createdAt : 0;
  const secondTimestamp = b.lastMessage && b.lastMessage.createdAt ? b.lastMessage.createdAt : 0;
  //Sort in DESC order
  return secondTimestamp - firstTimestamp;
});

Using the above code I'm able to sort an array of object in descending order.

Now, my requirement is first filter array based on ispin key. if ispin is set to true then I want to create new array object with key pin also in descending order and one more array with key recent in descending order.

So my final output should be like this.

{ 
  // first array object with key pin : filter by ispin:true and order by descending order
  pin: [
 {'name': 'test1', 'email': 'test1@gmail.com', 'ispin': true, 'updatedAt': 1540456416646}
 {'name': 'test3', 'email': 'test3@gmail.com', 'ispin': true, 'updatedAt': 1540456412541}
 ],
 // second array object with ket recent : order by descending order and records which has ispin false
 recent: [
 {'name': 'test2', 'email': 'test2@gmail.com', 'ispin': false, 'updatedAt': 1540456416111}
 {'name': 'test4', 'email': 'test4@gmail.com', 'ispin': false, 'updatedAt': 1540456414521}
 ]
}
Pac0
  • 21,465
  • 8
  • 65
  • 74
Dhaval
  • 1,393
  • 5
  • 29
  • 55
  • 1
    I believe you can achieve this by `.reduce()` method. You can create a new array which contains the objects which have `isPin:true`, then sort that array as you did earlier. – Umair Ahmed Oct 25 '18 at 08:59
  • 1
    @T.J.Crowder : I don't think this duplicate is a good one. I was writing an answer when you hammer closed the question, which was with a groupBy feature (using reduce as another comment mentioned). OP needs *grouping* here, not filtering, there can be much more better answer for this question than for the duplicate target. – Pac0 Oct 25 '18 at 09:06
  • 1
    ah right, I see it make no sense (and just realized it while looking at my answer). It should be `{ pin: [{}] }` – Pac0 Oct 25 '18 at 09:34

1 Answers1

1

To split your list depending on isPin value, you can do a grouping like this :

list = [
  {'name': 'test1', 'email': 'test1@gmail.com', 'ispin': true, 'updatedAt': 1540456416646},
  {'name': 'test2', 'email': 'test2@gmail.com', 'ispin': false, 'updatedAt': 1540456416111},
  {'name': 'test3', 'email': 'test3@gmail.com', 'ispin': true, 'updatedAt': 1540456412541},
  {'name': 'test4', 'email': 'test4@gmail.com', 'ispin': false, 'updatedAt': 1540456414521},
]

const groupBy = (array, fn) => array.reduce((result, item) => {
  const key = fn(item);
  if (!result[key]) result[key] = [];
  result[key].push(item);
  return result;
}, {});

const result = groupBy(list, x => x.ispin ? 'pin' : 'recent');
console.log(result);

(note : groupBy inspired from https://www.reddit.com/r/javascript/comments/4yi7e4/split_an_array_into_2_arrays_based_on_conditions/ ), and as said by the author of it, you can use groupBy from lodash instead, if you use this library.

Pac0
  • 21,465
  • 8
  • 65
  • 74