Подтвердить что ты не робот

Можно ли отсортировать объект карты 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 }
}
4b9b3361

Ответ 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"}