Reputation: 636
Hi am working on a chat application, i want to sort new message plus keeping the history order according to time.
For example i have the chat messages in an array like this, now am sorting them using the "time" key on each message object!
[{"user":"a", "msg":"Hi ", "read":true, "time":1}
{"user":"b", "msg":"Hi ", "read":false, "time":2}
{"user":"c", "msg":"Hi ", "read":false, "time":3}
{"user":"d", "msg":"Hi ", "read":true, "time":4}
{"user":"e", "msg":"Hi ", "read":true, "time":5}]
How can i also sort them using the "read" key where all false values should come on the top but the remaining objects should be sorted with the "time" key.
For example like this
[{"user":"b", "msg":"Hi ", "read":false, "time":2}
{"user":"c", "msg":"Hi ", "read":false, "time":3}
{"user":"a", "msg":"Hi ", "read":true, "time":1}
{"user":"d", "msg":"Hi ", "read":true, "time":4}
{"user":"e", "msg":"Hi ", "read":true, "time":5}]
Upvotes: 1
Views: 289
Reputation: 11
I'll recommend sorting the "read":false
and "read:true
values separately if possible.
Otherwise, you can simply sort the array twice using a stable sort algorithm (like merge sort). First by 'time' key and then by 'read' key.
PS: Underscore js (https://github.com/jashkenas/underscore) provides a sortBy function which it claims is stable.
PPS: If you want to do this exactly with one sort, use a combination of the two keys compare_key_generator = function(o){return o.read.toString()+o.time}
Upvotes: 0
Reputation: 4612
You could also create to array one for red messages and another for unred ones. All the more so since messages are already sorted by time :
var chat = [{"user":"b", "msg":"Hi ", "read":false, "time":2}, {"user":"c", "msg":"Hi ", "read":false, "time":3}, {"user":"a", "msg":"Hi ", "read":true, "time":1}, {"user":"d", "msg":"Hi ", "read":true, "time":4}, {"user":"e", "msg":"Hi ", "read":true, "time":5}];
var chatRed = chat.filter(x => x.read);
var chatNotRed = chat.filter(x => !x.read);
console.log(chatNotRed);
console.log(chatRed);
Upvotes: 0
Reputation: 386776
You could use Array#sort
and a callback for the sort order and chain the wanted sort parameter.
This callback uses the implicit converting of boolean to number with a calculation.
var array = [{ "user": "a", "msg": "Hi ", "read": true, "time": 1 }, { "user": "b", "msg": "Hi ", "read": false, "time": 2 }, { "user": "c", "msg": "Hi ", "read": false, "time": 3 }, { "user": "d", "msg": "Hi ", "read": true, "time": 4 }, { "user": "e", "msg": "Hi ", "read": true, "time": 5 }];
array.sort(function (a, b) {
return a.read - b.read || a.time - b.time;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 5
Reputation: 29946
var data = [{"user":"a", "msg":"Hi ", "read":true, "time":1},
{"user":"b", "msg":"Hi ", "read":false, "time":2},
{"user":"c", "msg":"Hi ", "read":false, "time":3},
{"user":"d", "msg":"Hi ", "read":true, "time":4},
{"user":"e", "msg":"Hi ", "read":true, "time":5}];
data.sort((a, b) => {
if (a.read === b.read) {
return a.time - b.time;
}
return a.read ? 1 : -1;
});
data.forEach(x => console.log(JSON.stringify(x)));
Upvotes: 0