2016-10-15 4 views
1

Привет, я работаю над чат-приложением, я хочу отсортировать новое сообщение и сохранить порядок истории в зависимости от времени.Javascript сортировать массив в порядке

Например, у меня есть сообщения чата в таком массиве, теперь я сортирую их, используя клавишу «время» для каждого объекта сообщения!

[{"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}] 

Как я могу также отсортировать их с помощью кнопки «читать», где все ложные ценности должны прийти на вершине, но остальные объекты должны быть отсортированы с помощью ключа «времени».

Например, как этого

[{"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}] 
+0

Как вы сортировочных прямо сейчас? – Amit

+0

Я бы начал с разбивки массива на один с прочитанными сообщениями, а один с нечитаемым, а затем отсортировал их независимо. Таким образом, вы все равно можете использовать готовый сортировщик. Или вы ищете конкретный код? – Ozgar

ответ

5

Вы можете использовать Array#sort и обратный вызов для порядка сортировки и цепей разыскиваемого рода параметр.

Этот обратный вызов использует неявное преобразование булевых чисел в число с вычислением.

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

+1

Эй, я думаю, вы делаете это наоборот, ложные значения должны идти в начало – Tuna

+0

@Tuna, верно, пропустили это. –

+1

Супер аккуратный! я бы сказал, что это один лайнер – Tuna

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

0

Можно также создать в массив один для красных сообщений, а другой для unred из них. Тем более, так как сообщения уже отсортированы по времени:

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

Я рекомендую сортировать значения "read":false и "read:true отдельно, если это возможно.

В противном случае вы можете просто отсортировать массив дважды, используя стабильный алгоритм сортировки (например, сортировка слияния). Сначала клавиша «время», а затем клавиша «читать».

PS: Подчеркивание js (https://github.com/jashkenas/underscore) обеспечивает функцию sortBy, которая, по ее утверждению, является стабильной.

PPS: Если вы хотите сделать это именно с одним сортом, используют комбинацию двух клавиш compare_key_generator = function(o){return o.read.toString()+o.time}

Смежные вопросы