如何在 JavaScript 中按值对映射进行排序?

如何按值对这张地图进行排序?

var map = new Map();
map.set('orange', 10);
map.set('apple', 5);
map.set('banana', 20);
map.set('cherry', 13);
125123 次浏览

在 ES6中,您可以这样做: (假设您的 Map 对象是 m)。

[...m].map(e =>{ return e[1];}).slice().sort(function(a, b) {
return a - b;
});

传播操作符将一个 Map 对象转换成一个数组,然后取出每个子数组的第二个元素来构建一个新数组,然后对它进行排序。如果要按降序排序,只需将 a - b替换为 b - a

您可以使用列表映射而不仅仅是映射。 试试这个:

var yourListMaps = [];
var a = {quantity: 10, otherAttr: 'tmp1'};
var b = {quantity: 20, otherAttr: 'tmp2'};
var c = {quantity: 30, otherAttr: 'tmp3'};
yourListMaps.push(a);
yourListMaps.push(b);
yourListMaps.push(c);

如果你想按数量排序,你可以:

// Sort c > b > a
yourListMaps.sort(function(a,b){
return b.quantity - a.quantity;
});

或者

// Sort a > b > c
yourListMaps.sort(function(a,b){
return a.quantity - b.quantity;
});

Yo 可以采取一种不同的方法,为自定义排序结果更改 Map.prototype[@@iterator]()Symbol.iterator

var map = new Map();


map.set("orange", 10);
map.set("apple", 5);
map.set("banana", 20);
map.set("cherry", 13);


map[Symbol.iterator] = function* () {
yield* [...this.entries()].sort((a, b) => a[1] - b[1]);
}


for (let [key, value] of map) {     // get data sorted
console.log(key + ' ' + value);
}


console.log([...map]);              // sorted order
console.log([...map.entries()]);    // original insertation order
.as-console-wrapper { max-height: 100% !important; top: 0; }

const myMap = new Map();
myMap.set("a",3);
myMap.set("c",4);
myMap.set("b",1);
myMap.set("d",2);


// sort by value
const mapSort1 = new Map([...myMap.entries()].sort((a, b) => b[1] - a[1]));
console.log(mapSort1);
// Map(4) {"c" => 4, "a" => 3, "d" => 2, "b" => 1}


const mapSort2 = new Map([...myMap.entries()].sort((a, b) => a[1] - b[1]));
console.log(mapSort2);
// Map(4) {"b" => 1, "d" => 2, "a" => 3, "c" => 4}


// sort by key
const mapSort3 = new Map([...myMap.entries()].sort());
console.log(mapSort3);
// Map(4) {"a" => 3, "b" => 1, "c" => 4, "d" => 2}


const mapSort4 = new Map([...myMap.entries()].reverse());
console.log(mapSort4);
// Map(4) {"d" => 2, "b" => 1, "c" => 4, "a" => 3}

您可以缩短这个函数并在 ES6中使用它-使用箭头函数(lambda)

 let m2= new Map([...m.entries()].sort((a,b) => b[1] - a[1]))

简单地使用

const sortedObject = mapObject.sort((a,b)=>return b.value - a.value)

这里有几个有效的答案,但是我认为“有序地图”方面不必要地使事情复杂化和混淆。

假设按值排序映射中的 钥匙列表,而不是按值排序条目的映射,就足够了,那么这样的方法就可以工作:

var map = {
orange: 10,
apple: 5,
banana: 20,
cherry: 13
}


var sorted_keys = Object.keys(map).sort(function(a,b) { return map[a] - map[b]; });

结果是:

["apple", "orange", "cherry", "banana"]

如果您实际上想要迭代映射条目(现在您需要迭代已排序的键数组并获取值) ,那么这样做就不那么优雅了,但是:

  1. 这个逻辑对于我简单的头脑来说更容易理解和记忆。

  2. 有一个非常常见的用例是“按值对这个映射进行排序”,在这个用例中,您实际上需要已排序的键列表: 使用映射来保持计数。(例如,使用映射对文件中的单词进行迭代,以保持每个单词出现的频率,然后按频率对映射进行排序,以获得单词列表。)

对于映射中的值不一定是数值的一般情况,将比较器函数(传递给 Object.keys(map).sort的函数)替换为:

function(a, b) {
return (a < b) ? -1 : ( (a > b) ? 1 : 0 );
}

(本质上是:

function(a, b) {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
}

而是使用三元操作符(? :)。)

但是请记住,对于混合类型,JavaScript 的 <>操作符的行为有时有点违反直觉,因此根据映射中的值,您可能希望在比较器中包含显式的类型转换逻辑。

使用下面的代码对映射对象进行排序。

const map = new Map();
map.set("key","value");
map.set("key","value");


const object = Object.keys(map.sort().reduce((a,b) => (a[k] = map[a], b), {});


console.log(object);


//This will work to sort a map by key.
let map = new Map();
map.set("apple", 1);
map.set("banana", 5);
map.set("mango", 4);
map.set("orange", 9);


let sorted = Object.keys(map).sort((a,b) => {
return map[b] - map[a];
});


console.log(sorted);

我还想按值对 Map 进行排序,但我的键是一个数字,value 是一个字符串。(Map < number,string >) ,并希望使用 打字机进行此操作。

这就是我使用 LocaleCompare的方法

let json = [
{
"key": 2952,
"value": "Sample Text"
},
{
"key": 2961,
"value": "Sample Text 1"
},
{
"key": 2962,
"value": "1Sample Text"
},
{
"key": 2987,
"value": "3Sample Text"
},
{
"key": 2988,
"value": "#Sample Text"
},
{
"key": 4585,
"value": "Ö Sample Text"
},
{
"key": 4594,
"value": "@Sample Text"
}
]


let myMap = new Map(Object.entries(json));


myMap = new Map([...myMap.entries()].sort((a, b) => a[1].value.localeCompare(b[1].value)));


myMap.forEach((x) => {
console.log(x.value)
})