# 【前端问题精选】字符串排序,小说章节排序算法？

``````const list = ['小说A第19章', '小说A第20章', '小说A第9章', '111', '小说B第五章', '小说B第四章'];

console.log(
list.sort((a, b) => {
return a > b ? 1 : -1;
})
);
// [ '111', '小说A第19章', '小说A第20章', '小说A第9章', '小说B第五章', '小说B第四章' ]
``````

``````[ '111', '小说A第9章', '小说A第19章', '小说A第20章', '小说B第四章',  '小说B第五章' ]

``````

``````'第五章' > '第四章'
// false

'第19章' > '第9章'
// false``````

### 回答：

``````const list = ["小说A第19章", "小说A第20章", "小说A第9章", "111", '222',"小说B第一千四百零二章","小说B第十五章", "小说B第四十二章", "小说B第二章", "小说B第四百零二章"];

function cnNum2Number(cnNumStr) {
const numList = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
if (cnNumStr[0] === "十") cnNumStr = "一" + cnNumStr;
const wTest = new RegExp(`([\${numList.join("")}])万`);
const qTest = new RegExp(`([\${numList.join("")}])千`);
const bTest = new RegExp(`([\${numList.join("")}])百`);
const sTest = new RegExp(`([\${numList.join("")}])十`);
const lTest = new RegExp(`([\${numList.join("")}])\$`);

let m = null;
const result = [wTest, qTest, bTest, sTest, lTest].map(t => (m = cnNumStr.match(t)) ? numList.indexOf(m[1]) : 0);

return parseInt(result.join(""));
}

function book2Item(list) {
const cnNum = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "百", "千", "万"];
return  list.map(k => {
if (!isNaN(parseInt(k))) {
return { text: k, book: "", index: parseInt(k) };
}
// 中文替换为数值
k = k.replace(new RegExp(`第([\${cnNum.join("")}]+)章\$`), (s, m) => s.replace(m, cnNum2Number(m)));
const result = { text: k, book: k.match(/^小说(.*)第/)[1] };
if (/第(\d+)章\$/.test(k)) {
return { ...result, index: +RegExp.\$1 };
}
return result;
});
}

function sortArrMap(arr) {
const map = {};
arr.forEach(it => {
const list = map[it.book] || (map[it.book] = []);
// if (!map[it.book]) return (map[it.book] = [it]);
const index = list.findIndex(item => item.index > it.index);
if (index === -1) return list.push(it);
list.splice(index, 0, it);
});

return map;
}

function sortBookList(list) {
const itemList = book2Item(list)
const map = sortArrMap(itemList)

return Object.keys(map).sort().reduce((pre, key) => {
return [...pre, ...map[key].map(i=>i.text)]
}, [])
}

console.log(sortBookList(list));
``````