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 }
}
답변
MDN 문서에 따르면 :
Map 객체는 삽입 순서에 따라 요소를 반복합니다.
다음과 같이 할 수 있습니다.
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)
를 사용 .sort()
하여 배열은 각 요소의 문자열 변환에 따라 각 문자의 유니 코드 코드 포인트 값에 따라 정렬됩니다. 따라서 2-1, 0-1, 3-1
올바르게 정렬됩니다.
답변
짧은 답변
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)))
같을 수없는 (동일한 문자열 키가 서로 덮어 쓰기) 키 문자열을 비교하면 equals 조건을 건너 뛸 수 있습니다. 그러나 다음과 같은 경우 lazy를 a[0] > b[0]
잘못 반환 하면 false (0으로 처리됨, 즉 같음)가 반환되므로 명시 적으로 -1을 반환해야합니다 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()))
그러나 이와 같이 강압과 문자열 화에 의존하는 것은 좋은 습관이 아닙니다. 다음과 같은 놀라움을 얻을 수 있습니다.
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())
}
이와 같은 버그는 디버그하기가 정말 어렵습니다. 위험을 감수하지 마십시오!
당신이 키 또는 값을 정렬 할 경우에 명시 적으로 접근하는 것이 가장 좋습니다 a[0]
과 b[0]
같이, 정렬 기능에. 우리가 반환해야 함을 참고 -1
하고 1
있지, 이전과 이후 false
또는 0
원시와 같은 a[0] > b[0]
이가 동등하게 취급되기 때문에 :
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] && 1) || (a[1] === b[1] ? 0 : -1)
console.log('By keys:', new Map([...map].sort(sortStringKeys)))
console.log('By values:', new Map([...map].sort(sortStringValues)))
답변
변환 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];
})
)
답변
아이디어는지도의 키를 배열로 추출하는 것입니다. 이 배열을 정렬하십시오. 그런 다음이 정렬 된 배열을 반복하고 정렬되지 않은 맵에서 값 쌍을 가져 와서 새 맵에 넣습니다. 새지도는 정렬 된 순서로 표시됩니다. 아래 코드는 구현입니다.
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);
답변
배열로 변환하고 배열 소링 메서드를 호출 할 수 있습니다.
[...map].sort(/* etc */);
답변
불행히도 ES6에서는 실제로 구현되지 않았습니다. ImmutableJS의 OrderedMap.sort () 또는 Lodash의 _.sortBy () 에이 기능이 있습니다 .
답변
한 가지 방법은 항목 배열을 가져 와서 정렬 한 다음 정렬 된 배열로 새 맵을 만드는 것입니다.
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);
})