Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

字符串排序,小说章节排序算法?

需要将一个小说目录排序。

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

中文数字转数字还挺麻烦的.
主要看第一个方法.
其余的实现很罗嗦.

即便这样,应该还有漏洞.先这样吧.

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));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...