Nodejs:对段落编号进行排序

时间:2016-07-28 15:19:48

标签: javascript node.js sorting

我正在尝试对从文档中提取的段落编号进行排序。

不幸的是,它们不是真正的小数,因此标准的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中完成这项工作?

非常感谢任何帮助

2 个答案:

答案 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);
    });
}

有趣的运动要做,稍后我会有所改进,当我有时间更多地工作时。