Можно ли отсортировать объект карты ES6?
Можно ли сортировать записи объекта карты es6?
var map = new Map();
map.set('2-1', foo);
map.set('0-1', bar);
результаты:
map.entries = {
0: {"2-1", foo },
1: {"0-1", bar }
}
Можно ли сортировать записи на основе их ключей?
map.entries = {
0: {"0-1", bar },
1: {"2-1", foo }
}
Ответы
Ответ 1
Согласно документации MDN:
Объект карты выполняет итерацию своих элементов в порядке размещения.
Вы можете сделать это следующим образом:
var map = new Map();
map.set('2-1', "foo");
map.set('0-1', "bar");
map.set('3-1', "baz");
var mapAsc = new Map([...map.entries()].sort());
console.log(mapAsc)
Ответ 2
Преобразовать Map
в массив с помощью Array.from
, сортировать массив, конвертировать обратно в Map
, например
new Map(
Array
.from(eventsByDate)
.sort((a, b) => {
// a[0], b[0] is the key of the map
return a[0] - b[0];
})
)
Ответ 3
Краткий ответ
new Map([...map].sort((a, b) =>
// Some sort function comparing keys with a[0] b[0] or values with a[1] b[1]
// Be sure to return -1 if lower and, if comparing values, return 0 if equal
))
Например, сравнивая строки значений, которые могут быть равны, мы передаем функцию сортировки, которая обращается к [1] и имеет условие равенства, которое возвращает 0:
new Map([...map].sort((a, b) => (a[1] > b[1] && 1) || a[1] === b[1] ? 0 : -1))
Сравнивая строки ключей, которые не могут быть равны (идентичные ключи строк перезаписывают друг друга), мы можем пропустить условие равенства. Однако мы все равно должны явно возвращать -1, потому что возврат ленивого a[0] > b[0]
неправильно дает false (трактуется как 0, то есть равно), когда a[0] < b[0]
:
new Map([...map].sort((a, b) => a[0] > b[0] ? 1 : -1))
Подробно с примерами
.entries()
в [...map.entries()]
(предлагается во многих ответах) является избыточным, возможно, добавляя дополнительную итерацию карты, если механизм JS не оптимизирует это для вас.
В простом тестовом примере вы можете выполнить то, о чем спрашивает вопрос:
new Map([...map].sort())
... который, если все ключи являются строками, сравнивает сжатые и принудительные строки значения ключа, разделенные запятыми, такие как '2-1,foo'
и '0-1,[object Object]'
, возвращая новую карту с новым порядком вставки:
Примечание: если вы видите только {}
в выводе консоли SO, посмотрите в своей настоящей консоли браузера
const map = new Map([
['2-1', 'foo'],
['0-1', { bar: 'bar' }],
['3-5', () => 'fuz'],
['3-2', [ 'baz' ]]
])
console.log(new Map([...map].sort()))
Ответ 4
Идея состоит в том, чтобы извлечь ключи вашей карты в массив. Сортируйте этот массив. Затем перебираем этот отсортированный массив, получаем его пару значений из несортированной карты и помещаем их в новую карту. Новая карта будет в отсортированном порядке. Код ниже - это реализация:
var unsortedMap = new Map();
unsortedMap.set('2-1', 'foo');
unsortedMap.set('0-1', 'bar');
// Initialize your keys array
var keys = [];
// Initialize your sorted maps object
var sortedMap = new Map();
// Put keys in Array
unsortedMap.forEach(function callback(value, key, map) {
keys.push(key);
});
// Sort keys array and go through them to put in and put them in sorted map
keys.sort().map(function(key) {
sortedMap.set(key, unsortedMap.get(key));
});
// View your sorted map
console.log(sortedMap);
Ответ 5
К сожалению, на ES6 не реализовано. У вас есть эта функция с OrderedMap.sort() от ImmutableJS или _. SortBy() от Lodash.
Ответ 6
Вы можете преобразовать в массив и вызвать методы поиска массива на нем:
[...map].sort(/* etc */);
Ответ 7
Один из способов - получить массив записей, отсортировать его, а затем создать новую карту с отсортированным массивом:
let ar = [...myMap.entries()];
sortedArray = ar.sort();
sortedMap = new Map(sortedArray);
Но если вы не хотите создавать новый объект, но для работы над одним и тем же, вы можете сделать что-то вроде этого:
// Get an array of the keys and sort them
let keys = [...myMap.keys()];
sortedKeys = keys.sort();
sortedKeys.forEach((key)=>{
// Delete the element and set it again at the end
const value = this.get(key);
this.delete(key);
this.set(key,value);
})
Ответ 8
Фрагмент ниже сортирует заданную карту по его клавишам и снова отображает ключи к объектам с ключом. Я использовал функцию localeCompare, так как моя карта была string-> строковая карта объекта.
var hash = {'x': 'xx', 't': 'tt', 'y': 'yy'};
Object.keys(hash).sort((a, b) => a.localeCompare(b)).map(function (i) {
var o = {};
o[i] = hash[i];
return o;
});
result: [{t:'tt'}, {x:'xx'}, {y: 'yy'}];
Ответ 9
Вы можете преобразовать карту в массив с помощью метода entries()
, отсортировать его как массив и создать новую карту из нее с помощью карты constuctor.
Ответ 10
Возможно, более реалистичный пример не сортировки объекта карты, а подготовки его перед началом работы с картой. Синтаксис становится довольно компактным, если вы делаете это так. Вы можете применить сортировку перед функцией карты, например, с помощью функции сортировки перед картой (пример из приложения React, над которым я работаю с использованием синтаксиса JSX)
Отметьте, что я здесь определяю функцию сортировки внутри, используя функцию стрелки, которая возвращает -1, если он меньше, и 0, в противном случае сортируется по свойству объектов Javascript в массиве, который я получаю из API.
report.ProcedureCodes.sort((a, b) => a.NumericalOrder < b.NumericalOrder ? -1 : 0).map((item, i) =>
<TableRow key={i}>
<TableCell>{item.Code}</TableCell>
<TableCell>{item.Text}</TableCell>
{/* <TableCell>{item.NumericalOrder}</TableCell> */}
</TableRow>
)
Ответ 11
let map = new Map();
map.set('2-1', "foo");
map.set('0-1', "bar");
map.set('3-1', "baz");
let mapAsc = new Map([...map.entries()].sort());
console.log(mapAsc);
// Map(3) {"0-1" => "bar", "2-1" => "foo", "3-1" => "baz"}