You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript排序函数异常:辐射能量与冲击能量列排序失效求助

问题

我是JavaScript新手,手里有个包含约1000条流星撞击数据的对象数组,已经实现了点击表头排序并渲染表格的功能,但radiatedEnergy和impactEnergy两列排序有问题:

  • radiatedEnergy是科学计数法格式的字符串(比如'3.75e14'),当前排序没法识别量级,判断不出3.75e14 > 15.2e10;
  • impactEnergy是数字格式的字符串(比如'440'),排序时只比首字符,不是完整数值。

相关代码如下:

HTML代码

<table class="table table-striped">
            <tr  class="bg-info">
                <th data-colname="date" data-order="desc"> Date/Time (UT) &#9650</th>
                <th data-colname="latitude">Latitude (deg) &#9650</th>
                <th data-colname="longitude" data-order="desc">Longitude (deg) &#9650</th>
                <th data-colname="altitude" data-order="desc">Altitude (km) &#9650</th>
                <th data-colname="velocity" data-order="desc">Velocity (km/s) &#9650</th>
                <th data-colname="vx" data-order="desc">vx &#9650</th>
                <th data-colname="vy" data-order="desc">vy &#9650</th>
                <th data-colname="vz" data-order="desc">vz &#9650</th>
                <th data-colname="radiatedEnergy" data-order="desc">Total Radiated Energy (J) &#9650</th>
                <th data-colname="impactEnergy" data-order="desc">Calculated Total Impact Energy (kt) &#9650</th>
            </tr>
    
            <tbody id="myTable"> </tbody>
        </table>

JavaScript代码

var myArray = [
            {'date': '2022-09-14 23:31:15' ,'latitude': '40.8N' ,'longitude': '63.4E'  ,'altitude': '35.8' ,'velocity': '17.4' ,'vx': '-13.9' ,'vy': '-4.3'  ,'vz': '9.5'   ,'radiatedEnergy': '15.2e10'   ,'impactEnergy': '0.11'},
            {'date': '2013-02-15 03:20:33' ,'latitude': '54.8N' ,'longitude': '61.1E'  ,'altitude': '23.3' ,'velocity': '18.6' ,'vx': '+12.8' ,'vy': '-13.3' ,'vz': '-2.4'  ,'radiatedEnergy': '3.75e14'  ,'impactEnergy': '440'},
            {'date': '2018-12-18 23:48:20' ,'latitude': '56.9N' ,'longitude': '172.4E' ,'altitude': '26.0' ,'velocity': '13.6' ,'vx': '6.3'   ,'vy': '-3.0'  ,'vz': '-31.2' ,'radiatedEnergy': '3.13e13'  ,'impactEnergy': '49'},
         ]
buildTable(myArray)   

$('th').on('click', function(){         
        var column = $(this).data('colname')
        var order = $(this).data('order')
        var text = $(this).html()
        text = text.substring(0, text.length - 1);
     
        if(order == 'desc') {
            $(this).data('order', "asc")
            myArray = myArray.sort((a,b) => a[column] > b[column] ? 1 : -1)
            text += '&#9660'     //appends triangle symbol based on ascending or descending            

        }else {
            $(this).data('order', "desc")
            myArray = myArray.sort((a,b) => a[column] < b[column] ? 1 : -1)
            text += '&#9650'
        }

    $(this).html(text)
    buildTable(myArray)
    })

                
    function buildTable(data){
        var table = document.getElementById('myTable')
        table.innerHTML = ''   

        for (var i = 0; i < data.length; i++){
            var colname = `num-${i}`
            var row = `<tr>
                <td>${data[i].date}</td>
                <td>${data[i].latitude}</td>
                <td>${data[i].longitude}</td>
                <td>${data[i].altitude}</td>
                <td>${data[i].velocity}</td>
                <td>${data[i].vx}</td>
                <td>${data[i].vy}</td>
                <td>${data[i].vz}</td>
                <td>${data[i].radiatedEnergy}</td>
                <td>${data[i].impactEnergy}</td>
            </tr>`
        table.innerHTML += row
            }
        }

解决方案

问题核心是当前排序直接用字符串比较,而非数值比较。针对不同列的格式,我们需要先把字符串转换成对应的数值,再进行排序。

修改后的JavaScript代码

var myArray = [
            {'date': '2022-09-14 23:31:15' ,'latitude': '40.8N' ,'longitude': '63.4E'  ,'altitude': '35.8' ,'velocity': '17.4' ,'vx': '-13.9' ,'vy': '-4.3'  ,'vz': '9.5'   ,'radiatedEnergy': '15.2e10'   ,'impactEnergy': '0.11'},
            {'date': '2013-02-15 03:20:33' ,'latitude': '54.8N' ,'longitude': '61.1E'  ,'altitude': '23.3' ,'velocity': '18.6' ,'vx': '+12.8' ,'vy': '-13.3' ,'vz': '-2.4'  ,'radiatedEnergy': '3.75e14'  ,'impactEnergy': '440'},
            {'date': '2018-12-18 23:48:20' ,'latitude': '56.9N' ,'longitude': '172.4E' ,'altitude': '26.0' ,'velocity': '13.6' ,'vx': '6.3'   ,'vy': '-3.0'  ,'vz': '-31.2' ,'radiatedEnergy': '3.13e13'  ,'impactEnergy': '49'},
         ]
buildTable(myArray)   

// 根据列名获取排序用的数值
function getSortValue(item, column) {
    const value = item[column];
    // 处理科学计数法和数字类字符串列
    if (['radiatedEnergy', 'impactEnergy', 'altitude', 'velocity', 'vx', 'vy', 'vz'].includes(column)) {
        // parseFloat可直接识别科学计数法和普通数字字符串
        return parseFloat(value);
    }
    // 处理带方向标识的经纬度
    if (['latitude', 'longitude'].includes(column)) {
        const num = parseFloat(value.slice(0, -1));
        const direction = value.slice(-1);
        // 南纬、西经转为负数,保证排序逻辑正确
        return direction === 'S' || direction === 'W' ? -num : num;
    }
    // 日期字符串直接返回,YYYY-MM-DD格式可直接按字典序正确排序
    return value;
}

$('th').on('click', function(){         
        var column = $(this).data('colname')
        var order = $(this).data('order')
        var text = $(this).html()
        text = text.substring(0, text.length - 1);
     
        if(order == 'desc') {
            $(this).data('order', "asc")
            // 用转换后的数值进行排序
            myArray = myArray.sort((a,b) => {
                const valA = getSortValue(a, column);
                const valB = getSortValue(b, column);
                return valA > valB ? 1 : -1;
            })
            text += '&#9660'            

        }else {
            $(this).data('order', "desc")
            myArray = myArray.sort((a,b) => {
                const valA = getSortValue(a, column);
                const valB = getSortValue(b, column);
                return valA < valB ? 1 : -1;
            })
            text += '&#9650'
        }

    $(this).html(text)
    buildTable(myArray)
    })

                
    function buildTable(data){
        var table = document.getElementById('myTable')
        table.innerHTML = ''   

        for (var i = 0; i < data.length; i++){
            var row = `<tr>
                <td>${data[i].date}</td>
                <td>${data[i].latitude}</td>
                <td>${data[i].longitude}</td>
                <td>${data[i].altitude}</td>
                <td>${data[i].velocity}</td>
                <td>${data[i].vx}</td>
                <td>${data[i].vy}</td>
                <td>${data[i].vz}</td>
                <td>${data[i].radiatedEnergy}</td>
                <td>${data[i].impactEnergy}</td>
            </tr>`
        table.innerHTML += row
            }
        }

关键修改说明

  1. 新增getSortValue函数:针对不同列的数据格式做适配转换:
    • 科学计数法、普通数字字符串列用parseFloat转为数值,解决字符串比较的逻辑错误;
    • 经纬度转换为正负数值,让南纬、西经能按实际地理位置排序;
    • 日期字符串保持原样,利用其格式特性直接比较即可。
  2. 修改排序回调逻辑:不再直接比较原始字符串,而是用转换后的数值进行大小比较,确保所有列的排序都符合实际业务逻辑。

内容的提问来源于stack exchange,提问作者aljames24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:55:22