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

如何在JavaScript中按值对映射进行排序?,javascript,sorting,dictionary,Javascript,Sorting,Dictionary,如何按值对该地图进行排序 var map = new Map(); map.set('orange', 10); map.set('apple', 5); map.set('banana', 20); map.set('cherry', 13); 在ES6中,您可以这样做:(假设您的地图对象是m) spread操作符将贴图对象转换为数组,然后取出每个子数组的第二个元素以构建新数组,然后对其进行排序。如果要按降序排序,只需将a-b替换为b-a即可使用列表映射,而不是仅使用映射。 试试这个: va

如何按值对该地图进行排序

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

在ES6中,您可以这样做:(假设您的地图对象是
m


spread操作符将贴图对象转换为数组,然后取出每个子数组的第二个元素以构建新数组,然后对其进行排序。如果要按降序排序,只需将
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;
});


对于自定义排序结果,您可以采用不同的方法和更改

var-map=newmap();
地图集(“橙色”,10);
地图集(“苹果”,5);
地图集(“香蕉”,20);
地图集(“樱桃”,13);
map[Symbol.iterator]=函数*(){
yield*[…this.entries()]排序((a,b)=>a[1]-b[1]);
}
对于(让map的[key,value]){//get数据排序
console.log(键+“”+值);
}
console.log([…map]);//排序顺序
console.log([…map.entries()]);//原始插入顺序

.as console wrapper{max height:100%!important;top:0;}
您可以缩短函数,并在ES6中使用此函数-使用箭头函数(lambda)


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

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"]
如果您确实想要迭代映射项(现在需要迭代排序键数组并获取值),那么这就不那么优雅了,但是:

  • 这个逻辑对我简单的头脑来说更容易遵循和记住

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

  • 对于映射中的值不一定是数字的一般情况,将comparator函数(传递给
    Object.keys(map).sort
    的函数)替换为如下内容:

    function(a, b) {
      return (a < b) ? -1 : ( (a > b) ? 1 : 0 );
    }
    
    功能(a、b){
    回报率(ab)-1:0);
    }
    
    (基本上是:

    function(a, b) {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    }
    
    功能(a、b){
    if(ab){
    返回1;
    }否则{
    返回0;
    }
    }
    
    但是使用三元(
    ?:
    )运算符。)


    但请记住,JavaScript的
    运算符的行为有时与混合类型有点不直观,因此根据映射中的值,您可能希望在比较器中包含显式类型转换逻辑。

    映射
    是一种数据结构,这是不应该被分类的。它存储键值对,对哈希表进行排序没有多大意义。您可以将其转换为数组,并对该数组进行排序,如果你愿意的话。我同意你不应该依赖于映射的排序使用普通对象而不是映射来存储按字母顺序排序的键:值对。我认为这很酷,但应该非常小心地使用,这样你就不会对已经排序的列表进行排序。事实上,我认为最好添加一个“isSorted”属性,如果是这样,那么就不要排序。我们可以更进一步,为二进制插入添加[Symbol.set]生成器,并为二进制搜索添加[Symbol.get],后者基于isSorted标志进行分叉。不过,我担心这种方法的长期安全性。我认为间接方式可能更为谨慎。这不起作用。我只按插入顺序得到结果现在再试一次?我想你是抄写错了什么?谢谢!你的方法很干净。但是,请您解释一下
    新映射([…myMap.entries()])
    。这个方法和Internet Explorer兼容吗?是的,我就是这么想的。有没有一个干净的方法可以与IE一起工作?
    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"]
    
    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;
      }
    }