是否可以对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 }
}
是否可以对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 }
}
Answers:
根据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()
,请记住,数组是根据每个字符的Unicode代码点值以及每个元素的字符串转换来排序的。因此2-1, 0-1, 3-1
将正确排序。
var mapAsc = new Map([...map.entries()].sort((a,b) => a[0] > b[0]));
使用箭头函数(lambda)
2-1,foo
0-1,bar
3-1,baz
(a,b) => a[0] > b[0]
!
...
点是重要的,否则你想排序MapIterator
1e-9
后100
的地图中放置数字。适用于数字的代码:new Map([...map.entries()].sort((e1, e2) => e1[0] - e2[0]))
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的equals条件的排序函数:
new Map([...map].sort((a, b) => (a[1] > b[1] && 1) || (a[1] === b[1] ? 0 : -1)))
比较不能相等的键字符串(相同的字符串键会互相覆盖),我们可以跳过equals条件。但是,我们仍然应该显式返回-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]'
,并返回具有新插入顺序的新Map:
注意:如果仅{}
在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];
})
)
[...map.values()].sort()
我没有工作,但Array.from(map.values()).sort()
没有
这个想法是将地图的键提取到一个数组中。对该数组排序。然后遍历此排序数组,从未排序映射中获取其值对,然后将其放入新映射中。新地图将按排序顺序。下面的代码是其实现:
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);
unsortedMap.keys()
。也keys.sort().map...
应该是keys.sort().forEach...
。
不幸的是,在ES6中并未真正实现。你有这个功能OrderedMap.sort()从ImmutableJS或_.sortBy()从Lodash。
一种方法是获取entry数组,对其进行排序,然后使用已排序的数组创建一个新Map:
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);
})
下面的代码段按键对给定的map进行排序,然后将键再次映射到键值对象。我使用localeCompare函数,因为我的地图是string-> 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;
});
结果: [{t:'tt'}, {x:'xx'}, {y: 'yy'}];
据我所知,目前无法正确分类地图。
将Map转换为数组并以这种方式排序的其他解决方案存在以下错误:
var a = new Map([[1, 2], [3,4]])
console.log(a); // a = Map(2) {1 => 2, 3 => 4}
var b = a;
console.log(b); // b = Map(2) {1 => 2, 3 => 4}
a = new Map(); // this is when the sorting happens
console.log(a, b); // a = Map(0) {} b = Map(2) {1 => 2, 3 => 4}
排序将创建一个新对象,所有其他指向未排序对象的指针都将损坏。
花2个小时了解细节。
请注意,问题的答案已经在https://stackoverflow.com/a/31159284/984471给出
但是,该问题的键不是通常的键,下面提供了
一个清晰且具有解释性的通用示例,它提供了一些更清晰的信息:
。
let m1 = new Map();
m1.set(6,1); // key 6 is number and type is preserved (can be strings too)
m1.set(10,1);
m1.set(100,1);
m1.set(1,1);
console.log(m1);
// "string" sorted (even if keys are numbers) - default behaviour
let m2 = new Map( [...m1].sort() );
// ...is destructuring into individual elements
// then [] will catch elements in an array
// then sort() sorts the array
// since Map can take array as parameter to its constructor, a new Map is created
console.log('m2', m2);
// number sorted
let m3 = new Map([...m1].sort((a, b) => {
if (a[0] > b[0]) return 1;
if (a[0] == b[0]) return 0;
if (a[0] < b[0]) return -1;
}));
console.log('m3', m3);
// Output
// Map { 6 => 1, 10 => 1, 100 => 1, 1 => 1 }
// m2 Map { 1 => 1, 10 => 1, 100 => 1, 6 => 1 }
// Note: 1,10,100,6 sorted as strings, default.
// Note: if the keys were string the sort behavior will be same as this
// m3 Map { 1 => 1, 6 => 1, 10 => 1, 100 => 1 }
// Note: 1,6,10,100 sorted as number, looks correct for number keys
希望能有所帮助。
关于不对Map对象进行排序,而是在执行Map之前预先准备排序的更现实的示例。如果您这样做,语法实际上会变得非常紧凑。您可以像这样在map函数之前应用排序功能,在map之前应用排序功能(我正在使用JSX语法的React应用示例)
标记为我在这里使用箭头函数定义了一个排序函数,如果箭头函数较小,该函数将返回-1;否则将返回0,否则将对我从API获得的数组中Javascript对象的属性进行排序。
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>
)
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"}