js数据类型对象(Object)自动排序问题

前言

这两天碰到一个问题。发现游戏(塔防类游戏)中炮塔寻怪算法有误,炮塔无法准确的找到最危险的怪物(也就是射程范围内离终点最近)。最后查看代码发现,以前怪物查询算法只需查询最危险的怪物,所以遍历所有的怪物,记录最危险那只就可以了。后来策划新增需求,炮塔需要短时间内陆续攻击最危险的N只怪。所以算法上就改成先将所有怪物排序,再取所需的怪物。因为排序有使用到两个变量排序用的 怪物剩余路程 和 怪物实例 。考虑到数组存储不方便,而且需要特别的写排序代码。想到Object是存在Key自动排序功能的,所以使用了一个Object去遍历后存储怪物(剩余路程为key,怪物实例为value)。最后事与愿违,并没有得到想要的结果。下面也就以此为例,带大家了解一下 对象(Object)的自动排序问题。

一、object的自动排序功能

我们在开发游戏的过程中常会遇到这种情况,将几个聊天频道的的聊天消息按时间顺序重新排序放到综合频道展示。或是服务器发了一堆战斗记录(不保证顺序)给我们展示。我们要快速的处理这些事情,经常会用到object的自动排序功能,下面代码做一段object的自动排序功能

var printObject = function(obj){
    console.log(`printObject begin`);
    var i = 0;
    for(var key in obj){
        console.log(`key${i} ${key}:${obj[key]}`);
        i++;
    }
    console.log(`printObject end`);
}

var randomObject = function(num){
    let numObj = {};
    for(var i = 0; i<num; i++){
        let numStr = Math.floor(Math.random()*3);
        let randomNum = Math.floor(Math.random()*(Math.pow(10, numStr)));
        console.log(`random key${i}:${randomNum}`);
        numObj[randomNum] = "fdsf";
    }
    printObject(numObj);
    return numObj;
}

二、object的自动排序测试

运行以上的随机函数结果如下:

运行: randomOjbect(5)
结果:
random key0:9
random key1:99
random key2:0
random key3:6
random key4:53
printObject begin
key0 0:fdsf
key1 6:fdsf
key2 9:fdsf
key3 53:fdsf
key4 99:fdsf
printObject end

运行: randomOjbect(5)
结果:
random key0:9
random key1:99
random key2:0
random key3:6
random key4:53
printObject begin
key0 0:fdsf
key1 6:fdsf
key2 9:fdsf
key3 53:fdsf
key4 99:fdsf
printObject end

三、Object混合属性的自动排序功能

以上两次运行结果可以发现,对象能对属性正确的自动排序,所以直觉的可以认为以number为属性的对象,都能以从小到大的顺序自动排序。但是事实真是如此吗?如果是这样,那文章一开头描述的问题又是什么情况呢?接下来我们对随机函数稍作修改,继续测试几次:

var randomObject = function(num, hasFloat){
    let numObj = {};
    for(var i = 0; i<num; i++){
        let numStr = Math.floor(Math.random()*6);
        let randomNum = Math.floor(Math.random()*(Math.pow(10, numStr)));
        let numLen = randomNum.toString().length;
        let dotpoint = Math.floor(Math.random()*numLen);//随机小数部分的位数
        if(hasFloat && Math.floor(Math.random()*2 === 0)){
            dotPoint = 0;
        }
        randomNum = randomNum/Math.pow(10, dotPoint);   //对整数进行小数处理
        console.log(`random key${i}:${randomNum}`);
        numObj[randomNum] = "fdsf";
    }
    printObject(numObj);
    return numObj;
}

四、混合自动排序测试


以上函数主要修改是,将在随机数中添加部分浮点数。这样整个属性中就有整形number,也有浮点型number。这样结果又会怎样呢?
下面一样随机允许两次看看结果

运行: randomOjbect(5, true)
结果:
random key0:7
random key1:4308
random key2:5.1
random key3:3
random key4:4.4605

printObject begin
key0 3:fdsf
key1 7:fdsf
key2 4308:fdsf
key3 5.1:fdsf
key4 4.4605:fdsf
printObject end

运行: randomOjbect(5, true)
结果:
random key0:39
random key1:447.5
random key2:69
random key3:5.26
random key4:7

printObject begin
key0 7:fdsf
key1 39:fdsf
key2 69:fdsf
key3 447.5:fdsf
key4 5.26:fdsf
printObject end

由上面的结果可以看出,属性排序后并不是完全由小到大的排序,其中分整数和浮点数部分,整数部分为数字大小从小到大排序。浮点数部分则并未排序,是按照放入的顺序排序。

总结


由此总结几点如下:

  • JS存在自动排序机制
  • 自动排序规则如下
    • 整数数字属性,按从小到大排序
    • 字符串属性,不进行自动排序。按照写入的顺序排序。
    • 浮点型属性,按照字符串属性方式处理
    • 同时存在整数数字类型和字符串类型时。优先排列整数数字类型。

下面提供 整数数字、浮点型数字、和字符串 三种属性的排序测试代码 【查看】

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值