Czy można posortować obiekt mapy ES6?
Czy możliwe jest sortowanie wpisów obiektu mapy es6?
var map = new Map();
map.set('2-1', foo);
map.set('0-1', bar);
Wyniki w:
map.entries = {
0: {"2-1", foo },
1: {"0-1", bar }
}
Czy możliwe jest sortowanie wpisów na podstawie ich kluczy?
map.entries = {
0: {"0-1", bar },
1: {"2-1", foo }
}
10 answers
Zgodnie z dokumentacją MDN:
Możesz to zrobić w ten sposób:Obiekt Map iteruje swoje elementy w kolejności wstawiania.
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)
Używając .sort()
, Należy pamiętać, że tablica jest sortowana według wartości punktu kodu Unicode każdego znaku, zgodnie z konwersją ciągu każdego elementu. Więc 2-1, 0-1, 3-1
będzie poprawnie posortowane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-01 11:18:53
Konwertuj Map
na tablicę za pomocą Array.from
, sort array, convert back to Map
, np.
new Map(
Array
.from(eventsByDate)
.sort((a, b) => {
// a[0], b[0] is the key of the map
return a[0] - b[0];
})
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-22 09:15:30
Chodzi o wyodrębnienie kluczy z mapy do tablicy. Posortuj tę tablicę. Następnie wykonaj iterację nad tą posortowaną tablicą, Pobierz jej parę wartości z niesortowanej Mapy i umieść je na nowej mapie. Nowa mapa będzie posortowana. Poniższy kod jest jego implementacją:
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-16 22:50:29
Można przekonwertować do tablicy i wywołać na niej metody sortowania tablic:
[...map].sort(/* etc */);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-08 19:24:28
Krótka odpowiedź
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
))
Na przykład, porównując ciągi wartości, które mogą być równe, przekazujemy funkcję sortowania, która uzyskuje dostęp [1] i ma warunek równy, który zwraca 0:
new Map([...map].sort((a, b) => a[1] === b[1] ? 0 : a[1] > b[1] ? 1 : -1))
Porównując łańcuchy kluczy, które nie mogą być równe (identyczne klucze łańcuchowe nadpisywałyby się nawzajem), możemy pominąć warunek equals. Jednak nadal powinniśmy zwracać jawnie -1, ponieważ zwracanie leniwego a[0] > b[0]
niepoprawnie daje false (traktowane jako 0, tzn. równe), gdy a[0] < b[0]
:
new Map([...map].sort((a, b) => a[0] > b[0] ? 1 : -1))
W szczegółach z przykładami
The .entries()
in [...map.entries()]
(sugerowane w wielu odpowiedziach) jest zbędny, prawdopodobnie dodając dodatkową iterację mapy, chyba że silnik JS zoptymalizuje to dla Ciebie.
W prostym przypadku testowym możesz zrobić to, o co prosi pytanie za pomocą:
new Map([...map].sort())
...które, jeśli wszystkie klucze są ciągami, porównuje zgniecione i wymuszone przecinkami łańcuchy wartości klucza, takie jak '2-1,foo'
i '0-1,[object Object]'
, zwracając nową mapę z nowym wstawianiem kolejność:
Uwaga: Jeśli widzisz tylko {}
na wyjściu konsoli SO, zajrzyj do prawdziwej konsoli przeglądarki
const map = new Map([
['2-1', 'foo'],
['0-1', { bar: 'bar' }],
['3-5', () => 'fuz'],
['3-2', [ 'baz' ]]
])
console.log(new Map([...map].sort()))
Jednak nie jest dobrą praktyką poleganie na takim przymusie i ciągnięciu. Możesz otrzymać niespodzianki takie jak:
const map = new Map([
['2', '3,buh?'],
['2,1', 'foo'],
['0,1', { bar: 'bar' }],
['3,5', () => 'fuz'],
['3,2', [ 'baz' ]],
])
// Compares '2,3,buh?' with '2,1,foo'
// Therefore sorts ['2', '3,buh?'] ******AFTER****** ['2,1', 'foo']
console.log('Buh?', new Map([...map].sort()))
// Let's see exactly what each iteration is using as its comparator
for (const iteration of map) {
console.log(iteration.toString())
}
Takie błędy są naprawdę trudne do debugowania - nie ryzykuj!
Jeśli chcesz sortować klucze lub wartości, najlepiej uzyskać do nich jawny dostęp za pomocą a[0]
i b[0]
w funkcji sortowania, jak to. Zauważ, że powinniśmy zwracać -1
i 1
przed i po, a nie false
lub 0
Jak z raw a[0] > b[0]
, ponieważ jest to traktowane jako równe:
const map = new Map([
['2,1', 'this is overwritten'],
['2,1', '0,1'],
['0,1', '2,1'],
['2,2', '3,5'],
['3,5', '2,1'],
['2', ',9,9']
])
// For keys, we don't need an equals case, because identical keys overwrite
const sortStringKeys = (a, b) => a[0] > b[0] ? 1 : -1
// For values, we do need an equals case
const sortStringValues = (a, b) => a[1] === b[1] ? 0 : a[1] > b[1] ? 1 : -1
console.log('By keys:', new Map([...map].sort(sortStringKeys)))
console.log('By values:', new Map([...map].sort(sortStringValues)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-09 12:24:10
Niestety, nie do końca zaimplementowane w ES6. Masz tę funkcję z OrderedMap.sort () from ImmutableJS or _.sortBy () z Lodash.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-15 12:05:14
Poniższy fragment sortuje mapę według swoich kluczy i mapuje Klucze do obiektów o wartości klucza ponownie. Użyłem funkcji localeCompare, ponieważ moja Mapa to string - > string object map.
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;
});
Wynik: [{t:'tt'}, {x:'xx'}, {y: 'yy'}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 22:23:43
Możesz przekształcić mapę w tablicę używając entries()
metoda, posortować ją jako tablicę i utworzyć z niej nową mapę za pomocą konstuktora Mapy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-01 10:52:43
Jednym ze sposobów jest pobranie tablicy wpisów, posortowanie jej, a następnie utworzenie nowej mapy z posortowaną tablicą:
let ar = [...myMap.entries()];
sortedArray = ar.sort();
sortedMap = new Map(sortedArray);
Ale jeśli nie chcesz tworzyć nowego obiektu, ale pracować na tym samym, możesz zrobić coś takiego:
// 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);
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 07:07:54
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"}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-28 06:13:13