【求助】js 数组排序问题

新手上路,请多包涵

现有数据格式如下

let arr=
[
    {
         name:'1',
         list:[
         {val:'-0.2%'},
         {val:'-0.1%'},
         {val:'--'},
         {val:'2021-04-04'},
         {val:'0.53%'},
         ....
         ]
     },
 {
         name:'2',
         list:[
         {val:'-0.14%'},
         {val:'-0.1%'},
         {val:'-0.45%'},
         {val:'2021-01-05'},
         {val:'0.53%'},
         ....
         ]
     },
 {
         name:'3',
         list:[
         {val:'-0.45%'},
         {val:'-0.1%'},
         {val:'-0.45%'},
         {val:'2021-02-01'},
         {val:'0.53%'},
         ....
         ]
     }
]

要求在排序的时候 需要以 arr[i].list[x].val来进行排序
1.如果数据有 -- 就放到最后
2.val数据格式不确定 但是就几种 带%号的string 可以转成float处理
日期格式 如果是日期格式那当前所有x的都是日期格式,不会x是日期 x+1却是%这种,但有可能是 -- 这种
数字格式 这种最好处理

其实用js数组自带的sort是能满足要求的,但是sort效率有点低,当arr数组长度很多的时候,会卡 放一下sort排序的方式,下面是没有包括日期的处理 排序

sort_list(index, orderby) {
             
                console.log(index,orderby)
                
                

                
                this.data_list_copy.sort(function (a, b) {
                    if(a.list[index].val == '--' || a.list[index].val == NaN){
                         return 1 ;
                    }
                    
                    if(b.list[index].val == '--' || b.list[index].val == NaN){
                        return -1 ;
                    }                    

                    if (parseFloat(a.list[index].val) < parseFloat(b.list[index].val)) {
                        return orderby == "desc" ? 1 : -1;
                    } else if (parseFloat(a.list[index].val) > parseFloat(b.list[index].val)) {
                        return orderby == "desc" ? -1 : 1;
                    }
                })
                
                
                
            },

求大佬给一下 排序效率更高效的方式

阅读 1.7k
2 个回答

使用 sort 即可, 数据排序前可以先 预处理,比如 parseFloat 等操作,甚至,按想要的排序给每一个项生成一个专用的排序 key, 对 key 进行排序即可

Array.prototype.sort() 一般是用的快速排序,不会很慢。之所在慢,应该是在每次比较的时候都会去重新计算用于比较的值,重复计算太多。所以基本思路就是准备好一切,包括把用于比较的值计算出来,再来排序。

下面代码,看注释。

function sort(list, valIndex, orderBy) {
    // 找一个对象,用来判断是按数值解析还是按日期解析,
    // 这个对象对应 valIndex 的值当然不能是--
    const markObj = arr.find(item => item.list[valIndex].val !== "--");
    if (!markObj) {
        // 如果没找到,说明全都是 --,那还比个什么劲
        return list;
    }

    const markVal = markObj.list[valIndex].val;
    // 把 -- 解析成无穷大。但如果一定要排最后的话,是无穷大还是无穷小由 orderBy 决定
    const parseDash = v => v === "--"
        ? orderBy === "desc" ? -Infinity : Infinity
        : undefined;
    // 根据 markVal 来决定 parse 函数
    const parse = markVal.endsWith("%")
        ? v => parseDash(v) ?? parseFloat(v)
        : v => parseDash(v) ?? new Date(v).getTime();
    // 根据 orderBy 来决定比较计算的方式
    const compare = (a, b) => orderBy === "desc"
        ? b - a
        : a - b;

    // 根据原数组生成用于排序的数组,这个数组由一对值组成
    // 第 1 个值表示要用于比较的 parse 出来的值,第 2 个值是原索引
    const assistant = list.map((it, i) => [parse(it.list[valIndex].val), i]);
    assistant.sort((a, b) => compare(a[0], b[0]));

    // 排序后按原索引找到对应的对象填充新数组,就是排序后的数组
    return assistant.map(([, i]) => list[i]);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题