一個不完整的,相當嚴格的方式做到這一點可能是這樣的:
'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);
});
}
有趣的練習做,我會回來以後有好轉,當我還得有更多的工作時間。
你永遠不需要比較一個數字和一個字母,是正確的嗎?例如,'3.4'和'3.a'永遠不需要比較? – apsillers
有些想法:你的子串是數字,在這種情況下,排序很簡單,或者它們是字母。在這種情況下,您可以嘗試執行查找表來對其進行編號轉換。唯一的問題將是羅馬數字('I','IV' ...),除非您找到一種方法可靠地將它們與簡單字母區分開來。 – DrakaSAN
@apsillers - 是的,這是正確的。所有的子字符串將是相同的類型。 – qts