使用JavaScript排序数组问题

时间:2018-09-29 16:47:16

标签: javascript arrays sorting

我正在尝试对该数组进行排序:

var arr = ["abc", "def", "1", "6", "4", "33", "10", "]", "20", "nike", "za", "(", "ABC"]; 

我希望排序的结果是:

["1", "4", "6", "10", "20", "33", "ABC", "abc", "def", "nike", "za", "(", "]"] 

我尝试了以下代码,但是问题是关于“ 10”的,它出现在“ 1”之后。我无法解决此问题。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:0)

一种查看每个字母和sorting with map模式的方法。

var array = ["abc", "def", "1", "6", "4", "33", "10", "]", "20", "nike", "za", "(", "ABC"],
    pattern = [                    // revers sorted
        c => /^[^a-z]*$/i.test(c), // all except letters
        c => /^[a-z]*$/.test(c),   // only lower letters
        c => /^[A-Z]*$/.test(c),   // only upper letters
    ],
    result = array
        .map((value, index) => /\d/.test(value)
            ? { index, value }
            : { index, value: Array.from(value, c => pattern.map(fn => fn(c) ? c : ' ').join('')).join('') }
        )
        .sort(({ value: a }, { value: b }) => isNaN(a) - isNaN(b) || a - b || a.localeCompare(b))
        .map(el => array[el.index]);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

这是一个相当复杂的排序。您是在要求数字按低序排列。这很简单。其他所有内容都要求非自然的升序排序,并以非单词字符结尾,而单词字符以大写字母优先排序,这与localeCompare的结果相反。

这是一个“强力”解决方案,它列举了每种可能性并适当地处理它们:

var arr = ["1", "4", "abc", "Abc", "20", "33", "ABC", "abc", "def", "nike", "za", "(", "]","1","-123", "6", "10", "20", "33", "4", "6", "10", "20", "33", "ABC", "abcd", "DEf", "nike", "za", "(", "]", "abc", "def", "nike", "za", "(", "([", "]","1", "4", "6", "10", "20", "33", "ABC", "abc", "def", "nike", "za", "](", "[]]","1", "4", "6", "10", "20", "10","%","$", "ABC", "33", "XYZ", "abc", "def", "nike", "za", "(", "]", "a"];

arr.sort((a, b) => {
  if (a.match(/^-?\d+$/)) {
    return b.match(/^-?\d+$/) ? (+a) - (+b) : -1;
  }
  else if (a.match(/^\w+$/)) {
    if (b.match(/^-?\d+$/)) {
      return 1;
    }
    else if (b.match(/^\w+$/)) {
      if (a.match(/^[A-Z]/)) {
        if (b.match(/^[A-Z]/)) {
          const aLen = a.match(/^[A-Z]+/)[0].length;
          const bLen = b.match(/^[A-Z]+/)[0].length;
          
          if (aLen !== bLen) {
            return bLen - aLen;
          }

          return a.localeCompare(b);
        }
        
        return -1;
      }
      
      return b.match(/^[A-Z]/) ? 1 : a.localeCompare(b);
    }
    
    return -1;
  }
  else if (b.match(/^-?\d+$/) || b.match(/^\w+$/)) {
    return 1;
  }
  
  return a.localeCompare(b);  
});

console.log(arr);

答案 2 :(得分:0)

似乎您可以使用options上的localeCompare解决大部分问题。要最后对非字母数字进行排序,可以在排序中添加一个简单的正则表达式:

var arr = ["abc", "def", "1", "6", "4", "33", "10", "]", "20", "nike", "za", "(", "ABC"]; 

let re = new RegExp('[0-9a-z]', 'i')
arr.sort((a,b) =>  
     (re.test(b) - re.test(a)) 
     || a.localeCompare(b, 'en', {numeric: true, caseFirst:"upper"}))

console.log(arr)