如何在 JavaScript 中按值对地图进行排序?

Posted

技术标签:

【中文标题】如何在 JavaScript 中按值对地图进行排序?【英文标题】:How to sort a map by value in JavaScript? 【发布时间】:2016-10-25 05:57:15 【问题描述】:

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

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

【问题讨论】:

Map 是一种数据结构,应该是不能排序的。它存储键值对,对哈希表进行排序没有多大意义。您可以将其转换为数组,并根据需要对该数组进行排序。 我同意你不应该依赖于那种地图 Sort a dictionary by value in javascript的可能重复 使用普通对象而不是地图来存储按字母顺序排序的键值对。 【参考方案1】:
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

【讨论】:

谢谢!你的方法很干净。但是,您能否解释一下new Map([...myMap.entries()])。此方法与 Internet Explorer 兼容吗? Looks like you can't use the array spread operator in IE 是的,这就是我的想法。任何适用于 IE 的干净方法的想法?【参考方案2】:

你可以采取不同的方法,将Symbol.iteratorMap.prototype[@@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; 

【讨论】:

我认为这很酷,但应该非常小心地使用,这样您就不会对已经排序的列表进行排序。 事实上,我认为添加一个“isSorted”属性会很好,如果是这样就不要排序。可以更进一步,为二进制插入添加一个 [Symbol.set] 生成器,并为基于 isSorted 标志分叉的二进制搜索添加 [Symbol.get]。我担心这种方法的长期安全性。我认为间接可能会更谨慎。【参考方案3】:

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

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

展开运算符将一个 Map 对象变成一个数组,然后取出每个子数组的第二个元素构建一个新数组,然后对其进行排序。如果您想按降序排序,只需将a - b 替换为b - a

【讨论】:

【参考方案4】:

你可以缩短函数并在 ES6 中使用它——使用箭头函数 (lambda)

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

【讨论】:

【参考方案5】:

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

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;
);

【讨论】:

这不起作用。我只在广告订单中得到结果 现在再试一次?我认为你抄袭或写错了什么?【参考方案6】:

要对地图对象进行排序,请使用以下代码。

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.

【讨论】:

【参考方案7】:
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);

【讨论】:

【参考方案8】:

要对对象进行排序,只需使用

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

【讨论】:

sort() 不是 Map 类型的函数。【参考方案9】:

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

假设在映射中获取按值排序的 列表就足够了,而不是其条目按值排序的映射,那么这样的工作:

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"]

如果您真的想要遍历映射条目(现在您需要遍历排序键数组并获取值),这会不太优雅,但是:

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

    有一个非常常见的用例“按值排序此映射”,您实际上需要排序后的键列表:使用映射来保持计数。 (例如,使用映射遍历文件中的单词以不断尝试每个单词出现的频率,然后对该映射进行排序以获得按频率排列的单词列表。)

对于映射中的值不一定是数字的一般情况,请将比较器函数(传递给 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 的 &lt;&gt; 运算符的行为有时与混合类型有点反直觉,因此根据映射中的值,您可能希望在您的比较器。

【讨论】:

以上是关于如何在 JavaScript 中按值对地图进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在PHP中按值对对象数组进行排序

在Python中按值对嵌套字典进行排序,并按另一个值对余数进行排序

在python中按值对defaultdict进行排序

如何在reactjs / javascript中按值对对象数组进行分组

在 Java 中按值映射自动排序

如何按值对 STL 映射进行排序?