数字版本号排序,非数字排序

数字版本号排序,非数字排序


4种排序函数以及耗时

  • 2、3方式,循环比较
  • 1 方式,转数据类型节省sort里面的循环比较(直接比较)
  • 4 方式,转数据类型后采用桶排序节省大部分Array.sort排序的时间(数据量庞大时优势明显)
  • 不限制排序的数据格式,只需要转为对应的数字
  • 易重写
/**
 * 桶排序
 * @param {Array<object>} arr 数组
 * @param {function(object): number} build 项构造器,返回数字
 */
function bucketSorting(arr, build) {
    const numbers = arr.map(build), list = new Array(Math.floor(arr.length / 2)), result = [];
    let min = numbers[0], max = numbers[0], c = 0;
    while (++c < numbers.length) {
        if (numbers[c] < min) {
            min = numbers[c];
        }
        if (numbers[c] > max) {
            max = numbers[c];
        }
    }
    for (let i = 0; i < list.length; i++) {
        list[i] = [];
    }
    const difference = max - min;
    c = -1;
    while (++c < numbers.length) {
        const n = numbers[c];
        list[Math.floor((n - min) / difference * (list.length - 1))].push(c);
    }
    list.map(e => e.sort((a, b) => numbers[a] - numbers[b])).forEach(e => (e || []).forEach(a => result.push(numbers[a])));
    return result;
}
  1. 采用 转数据类型+排序
/**
 * 只要不是1.1.1.1.1....这种点点特多的情况,完全可以忽略精度问题。
 * @param {Array<string>} versions
 */
function versionSort(versions = []) {
    return versions.map((b, index) => {
        return {
            number: b.split(".").map((c, i) => +("0." + c) * Math.pow(10, 5 - i)).reduce((b, c) => b + c),
            value: b
        }
    }).sort((b, c) => b.number - c.number).map(e => e.value);
}
  1. 采用 排序+循环
/**
 * @param {Array<String>} versions
 */
function versionSortLoop(versions = []) {
    return versions.sort((a, b) => {
        const _a = a.split(".").map(e => +e);
        const _b = b.split(".").map(e => +e);
        while (_a.length > 0) {
            const fisrt = _a.shift();
            const two = _b.shift() || 0;
            if (fisrt > two) {
                return 1;
            } else if (fisrt < two) {
                return -1;
            }
        }
        return 0;
    });
}
  1. 采用百度方式
function sortVersion(list) {
    return list.sort((version1, version2) => {
        const arr1 = version1.split('.').map(e => e * 1)
        const arr2 = version2.split('.').map(e => e * 1)
        const length = Math.max(arr1.length, arr2.length)
        for (let i = 0; i < length; i++) {
            if ((arr1[i] || 0) > (arr2[i] || 0)) return 1
            if ((arr1[i] || 0) < (arr2[i] || 0)) return -1
        }
        return 0
    })
}
  1. 采用桶排序+转数据类型+sort排序
function versionSortBucket(versions = []) {
    return bucketSorting(versions.map((b, index) => {
        return {
            number: b.split(".").map((c, i) => +("0." + c) * Math.pow(10, 5 - i)).reduce((b, c) => b + c),
            value: b
        }
    }), (e) => e.number).map(e => e.value);
}
class Log {
    run(func, title) {
        console.log("------------" + title + "------------");
        func();
        console.log("------------------------");
    }
    static runTime(func) {
        const beginTime = new Date();
        func();
        const endTime = new Date();
        const consume = endTime - beginTime;
        return consume;
    }
}

const log = new Log();
const a = ['0.1.1', '0.1.0.1', '2.3.3', '0.3002.1', '4.2', '4.2.1', '4.3.5', '4.3.5.1', '4.3.4.5'];
const a1 = ['0.1.1', '0.1.0.1', '2.3.3', '0.3002.1', '4.2', '4.2.1', '4.3.5', '4.3.5.1', '4.3.4.5'];
let c;

c = 1000;
while (--c > 0) {
    a1.push([Math.random(), Math.random(), Math.random()].join("."));
}
c = 20;
log.run(() => {
    while (--c >= 0) {
        console.log(`${20 - c}次测试:\tversionSortLoop\t${Log.runTime(() => versionSortLoop(a1))}ms\tversionSort\t${Log.runTime(() => versionSort(a1))}ms\tsortVersion\t${Log.runTime(() => sortVersion(a1))}ms`);
    }
}, "少数据测试," + a1.length);

c = 10000;
while (--c > 0) {
    a.push([Math.random(), Math.random(), Math.random()].join("."));
}
c = 20;
log.run(() => {
    while (--c >= 0) {
        console.log(`${20 - c}次测试:\tversionSortLoop\t${Log.runTime(() => versionSortLoop(a))}ms\tversionSort\t${Log.runTime(() => versionSort(a))}ms\tsortVersion\t${Log.runTime(() => sortVersion(a))}ms`);
    }
}, "多数据测试," + a.length);

测试结果排序
桶排序比较结果
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值