简体   繁体   中英

Javascript sort array in order

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}]

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; } 

 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))); 

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);

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}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM