假如,有这么一个需求,就是要求在前端页面展示一些商品,我们假设,这些要展示的商品有个字段叫权重,现在问题来了,要求你对这个商品的展示是根据这个权重来排序的,值大的靠前,或者值小的靠前,你该怎么做?
首先,你会说,这简单啊,后端排好序直接展示就行了。对,这没错,是可以的。但是假如你家的后端比较个性化,返回的数据结构是在一个对象里呢?严格来说,数组类型的数据结构是有顺序的,但是对象就不是了,即使后端在对象里排好了序,你会发现,在我们前端界,在浏览器里,竟然不能按照自己想要的顺序来显示,明明后端都给你排好了啊!你说为什么会这样,我也不知道,可能是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);
});
完~