我正在尝试对从文档中提取的段落编号进行排序。
不幸的是,它们不是真正的小数,因此标准的sort
函数不起作用。例如,我想要以下结果:["3.1","3.2","3.11"]
NOT ["3.1","3.11","3.2"]
(这是我从使用中获得的:http://www.w3schools.com/jsref/jsref_sort.asp)。
这些数字也有不确定的小数位数。例如,它们可以显示如下:["1.i.a","1.i.b","1.i.c.A","1.i.c.B"]
在解决了这个问题一段时间之后,我认为最好的解决方案是将每个数字视为由'分隔的子字符串,并根据'进行比较/排序。最低'串。
有谁能建议如何在JS中完成这项工作?
非常感谢任何帮助
答案 0 :(得分:1)
这对你有用吗?如果需要,我可以给出更多解释。
"use strict"
let index = ['3.1.a', '3.2', '3.11', '3.1.c', '3.2.z'];
index.sort((a, b) => {
var aArr = a.split('.'), bArr = b.split('.')
for (var i = 0, aLength = aArr.length; i < aLength; i++) {
let aVal = aArr[i], bVal = bArr[i]
if (!isNaN(aVal)) aVal = Number(aVal) // convert substring into Number if it is a Number
if (!isNaN(bVal)) bVal = Number(bVal)
if (bVal === undefined) return 1 // b lower index
if (aVal === bVal) continue
return typeof(aVal) === "string" ? aVal.charCodeAt() - bVal.charCodeAt() : aVal - bVal; // for strings, works only if length == 1
}
return bArr[i] === undefined ? 0 : -1 // if b undefined, then both numbers are equal, otherwise a is shorter
})
console.log(index)
// outputs [ '3.1.a', '3.1.c', '3.2', '3.2.z', '3.11' ]
答案 1 :(得分:0)
一种不完整且非常严格的方法可能是:
'use strict';
const async = require('async');
let index = ['3.1.a', '3.2', '3.11', '3.1.c', '3.2.z'];
//'3.1.a' => ['3', '1', 'a']
function paragraphToSubstring(string, callback) {
async.map(string, (s, callback) => {
callback(null, s.split('.'));
}, (err, substrings) => {
callback(substrings);
});
}
//['3', '1', 'a'] => [3, 1, 1]
function substringToNumber(substrings) {
async.map(substrings, (e, callback) {
let i = parseInt(e);
//If e is a letter
if(isNaN(i)) {
//Take it's ASCII value
//If you need to support roman number, you'll have to make the check and transformation here
callback(null, e.charCodeAt(0));
} else {
callback(null, i);
}
})
}
function sort(paragraphs, callback) {
async.waterfall([
//Convert everything in array
(callback) => {
async.map(paragraphs, (p, callback) => {
paragraphToSubstring(p, (s) => {
callback(null, s);
});
}, (err, substrings) => {
callback(err, substrings)
});
},
//Convert everything in numbers
(substrings, callback) => {
async.map(substrings, (s, callback) => {
substringToNumber(s, (err, i) => {
callback(err, i);
});
}, (err, numbers) => {
callback(err, numbers);
});
}
//Sort
(numbers, callback) => {
callback(null, numbers.sort((a, b) => {
//Didn't found a way to support a undefinite number of element, settled on 3
let s1 = a[0] - b[0],
s2 = a[1] - b[1],
s3 = a[2] - b[2];
if(s1) {
return s1;
}
if(s2) {
return s2;
}
if(s3) {
return s3;
}
}));
}
], (err, sorted) {
callback(err, sorted);
});
}
有趣的运动要做,稍后我会有所改进,当我有时间更多地工作时。