如此熟:JS中关于对象排序的问题

534 阅读3分钟

假如,有这么一个需求,就是要求在前端页面展示一些商品,我们假设,这些要展示的商品有个字段叫权重,现在问题来了,要求你对这个商品的展示是根据这个权重来排序的,值大的靠前,或者值小的靠前,你该怎么做?

首先,你会说,这简单啊,后端排好序直接展示就行了。对,这没错,是可以的。但是假如你家的后端比较个性化,返回的数据结构是在一个对象里呢?严格来说,数组类型的数据结构是有顺序的,但是对象就不是了,即使后端在对象里排好了序,你会发现,在我们前端界,在浏览器里,竟然不能按照自己想要的顺序来显示,明明后端都给你排好了啊!你说为什么会这样,我也不知道,可能是JS中对象本就是个无序的,浏览器做好事自动帮我们按照某种大小关系进行了排序,方便我们查看。所以,你解析循环显示出来的,就已经是自动排好序过后的数据了。这时候,我们要怎么做呢?

let obj={3:[{id:3,name:3},{id:3,name:3}],2:[{id:2,name:2},{id:2,name:2}],1:[{id:1,name:1},{id:1,name:1}]};
console.log(obj);

你会发现,上面排好序的JSON对象,在浏览器中调试时,顺序居然是这样的! 如果我们需要按3,2,1的顺序来显示这个,可能你会这样做:

let obj={3:[{id:3,name:3},{id:3,name:3}],2:[{id:2,name:2},{id:2,name:2}],1:[{id:1,name:1},{id:1,name:1}]};
//取对象键并进行排序
  let objIndex = Object.keys(obj).sort((a, b) => {
      return b - a;
    });
//循环排好的值,得到符合要求的显示顺序
    objIndex.forEach(index => {
      console.log(obj[index]);
    });

得到我们想要的顺序显示

这种方法也是可以的,但是不完美,因为这会让我们多维护一个变量objIndex。那么,更好的办法是什么呢?

我们可以使用ES比较新的数据结构,Map()数据结构(相应的还有Set()数据结构)。在这之前,你需要了解Map()和[1,2].map()中map()两者的区别,前者是一种数据结构,后者是数组类型结构中的一种遍历方法。

Map()数据结构的操作方法

set(key, value): 向 Map 中加入或更新键值对

get(key): 读取 key 对用的值,如果没有,返回 undefined

has(key): 某个键是否在 Map 对象中,在返回 true 否则返回 false

delete(key): 删除某个键,返回 true, 如果删除失败返回 false

clear(): 删除所有元素

Map()数据结构的遍历方法

keys():返回键名的遍历器

values():返回键值的遍历器

entries():返回所有成员的遍历器

forEach():遍历 Map 的所有成员

let obj={3:[{id:3,name:3},{id:3,name:3}],2:[{id:2,name:2},{id:2,name:2}],1:[{id:1,name:1},{id:1,name:1}]};

obj = new Map(Object.entries(obj));
    console.log(obj, "对象转为map数据结果");

    obj = Array.from(obj);
    console.log(obj, "map数据转Array结构");

    obj.sort(function(a, b) {
      return b[0] - a[0];
    });
    console.log(obj, "排序后结果");
    obj.forEach(e => {
      console.log(e, "直接使用排序好的Array结构");
    });

    //如果不使用Array结构,可以再转换成Map()结构和对象结构
    obj = new Map(
      obj.map(i => {
        return [i[0], i[1]];
      })
    );
    console.log(obj, "排序后数组转map对象");
    
    obj.forEach(e => {
      console.log(e, "转回Map()结构后的显示");
    });

    obj.forEach((e, index) => {
      console.log("取里面的值:", index, ",", e);
    });

完~