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) ▲</th> <th data-colname="latitude">Latitude (deg) ▲</th> <th data-colname="longitude" data-order="desc">Longitude (deg) ▲</th> <th data-colname="altitude" data-order="desc">Altitude (km) ▲</th> <th data-colname="velocity" data-order="desc">Velocity (km/s) ▲</th> <th data-colname="vx" data-order="desc">vx ▲</th> <th data-colname="vy" data-order="desc">vy ▲</th> <th data-colname="vz" data-order="desc">vz ▲</th> <th data-colname="radiatedEnergy" data-order="desc">Total Radiated Energy (J) ▲</th> <th data-colname="impactEnergy" data-order="desc">Calculated Total Impact Energy (kt) ▲</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 += '▼' //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 += '▲' } $(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 += '▼' }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 += '▲' } $(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 } }
关键修改说明
- 新增
getSortValue函数:针对不同列的数据格式做适配转换:- 科学计数法、普通数字字符串列用
parseFloat转为数值,解决字符串比较的逻辑错误; - 经纬度转换为正负数值,让南纬、西经能按实际地理位置排序;
- 日期字符串保持原样,利用其格式特性直接比较即可。
- 科学计数法、普通数字字符串列用
- 修改排序回调逻辑:不再直接比较原始字符串,而是用转换后的数值进行大小比较,确保所有列的排序都符合实际业务逻辑。
内容的提问来源于stack exchange,提问作者aljames24
相关产品推荐
相关产品推荐

