对带点的混合字母数字字符串列表进行排序?

时间:2020-04-17 13:23:28

标签: javascript sorting alphanumeric

我有一个需要使用tab属性进行排序的对象数组。

所有值都是字母数字字符串。

我已经设置了一个示例来向您展示我到目前为止所拥有的东西,而我似乎无法开始工作。

我需要将我的列表排序为doc1, doc2, doc3... doc12, doc13, doc14

// Sort set of values both lexicographically and numerically
function myComparator({ tab: value1 }, { tab: value2 }) {
  const _value1 = parseFloat(value1);
  const _value2 = parseFloat(value2);

  if (_value1 - _value2 === 0) {
    return (value1 > value2) ? 1 : -1;
  } else {
    return _value1 - _value2;
  }
}

const myArray = [
  { doc: 'Doc1', tab: '7' },
  { doc: 'Doc2', tab: '7A' },
  { doc: 'Doc3', tab: '7B' },
  { doc: 'Doc4', tab: '7.0001' },
  { doc: 'Doc5', tab: '7.01' },
  { doc: 'Doc6', tab: '7.01A' },
  { doc: 'Doc7', tab: '7.1' },
  { doc: 'Doc8', tab: '7.1A' },
  { doc: 'Doc9', tab: '7.2' },
  { doc: 'Doc10', tab: '7.3' },
  { doc: 'Doc11', tab: '7.10' },
  { doc: 'Doc12', tab: '7.11' },
  { doc: 'Doc13', tab: '7.20' },
  { doc: 'Doc14', tab: '7.34' },
];

myArray.sort(myComparator);

let html = '';

for (let i = 0; i < myArray.length; i++) {
  html += '<li>' + myArray[i].doc + '</li>';
}

document.getElementById('results').innerHTML = html;
<ul id="results" />

1 个答案:

答案 0 :(得分:0)

将许多其他代码段组合在一起以找到解决方案。见下文:

function customSort(data, key, order) {
    function isNumber(v) {
        return (+v).toString() === v;
    }

    function isRoman(s) {
        // http://stackoverflow.com/a/267405/1447675
        return /^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/i.test(s);
    }

    function parseRoman(s) {
        var val = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };
        return s.toUpperCase().split('').reduce(function (r, a, i, aa) {
            return val[a] < val[aa[i + 1]] ? r - val[a] : r + val[a];
        }, 0);
    }

    var sort = {
            asc: function (a, b) {
                var i = 0,
                    l = Math.min(a.value.length, b.value.length);

                while (i < l && a.value[i] === b.value[i]) {
                    i++;
                }
                if (i === l) {
                    return a.value.length - b.value.length;
                }
                if (isNumber(a.value[i]) && isNumber(b.value[i])) {
                    return a.value[i] - b.value[i];
                }
                if (isRoman(a.value[i]) && isRoman(b.value[i])) {
                    return parseRoman(a.value[i]) - parseRoman(b.value[i]);
                }
                return a.value[i].localeCompare(b.value[i]);
            },
            desc: function (a, b) {
                return sort.asc(b, a);
            }
        };
        
        var mapped = data.map(function (el, i) {
            var string = el[key].replace(/\d(?=[a-z])|[a-z](?=\.)/gi, '$&. .'),
                regex = /(\d+)|([^0-9.]+)/g,
                m,
                parts = [];

            while ((m = regex.exec(string)) !== null) {
                parts.push(m[0]);
            }
            return { index: i, value: parts, o: el, string: string };
        });

    mapped.sort(sort[order] || sort.asc);
    return mapped.map(function (el) {
        return data[el.index];
    });
}

var arr = [
	{ doc: 'Doc10', tab: '7.3' },
	{ doc: 'Doc2', tab: '7B' },
  { doc: 'Doc13', tab: '7.20' },
  { doc: 'Doc0', tab: '7' },
  { doc: 'Doc1', tab: '7A' },
  { doc: 'Doc3', tab: '7C' },
  { doc: 'Doc4', tab: '7.0001' },
  { doc: 'Doc5', tab: '7.01' },
  { doc: 'Doc6', tab: '7.01A' },
  { doc: 'Doc7', tab: '7.1' },
  { doc: 'Doc8', tab: '7.1A' },
  { doc: 'Doc9', tab: '7.2' },
  { doc: 'Doc11', tab: '7.10' },
  { doc: 'Doc12', tab: '7.11' },
  { doc: 'Doc14', tab: '7.34' }
];

const myArray = customSort(arr, 'tab');

let html = '';

for (let i = 0; i < myArray.length; i++) {
  html += '<li>' + myArray[i].doc + '</li>';
}

document.getElementById('results').innerHTML = html;
<ul id="results" />

我要找的正确顺序是:

  • 7
  • 7A
  • 7B
  • 7.0001
  • 7.01
  • 7.01A
  • 7.1
  • 7.1A
  • 7.2
  • 7.3
  • 7.10
  • 7.11
  • 7.20
  • 7.34
相关问题