使用特殊字符在Javascript中排序

时间:2012-06-08 14:50:58

标签: javascript arrays sorting

我有一个包含以下值的数组

asd sdf dsdf 1sadf *sdf !sdf @asdf _asd .sadf (sadf )sadf #sadf 
^asdf &asdf %asdf -sadf =sadf +sadf -sdf

我希望在javascript中按以下方式将其排序为三个部分。

  1. 从特殊字符开始的单词
  2. 从数字开始的字
  3. 从字母开始的单词。
  4. 所以这应该是排序数组的序列。

    修改: 这是我一直在尝试的功能:

    function naturalSort(a, b) {
       a = a.path.toLowerCase();
       b = b.path.toLowerCase();
       var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
      sre = /(^[ ]*|[ ]*|[_]*$)/g,
      dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
      hre = /^0x[0-9a-f]+$/i,
      ore = /^0/,
       // convert all to strings and trim()
      x = a.toString().replace(sre, '') || '',
      y = b.toString().replace(sre, '') || '',
       // chunk/tokenize
      xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
      yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
       // numeric, hex or date detection
      xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
      yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null;
       // first try and sort Hex codes or Dates
       if (yD)
        if (xD < yD) return -1;
        else if (xD > yD) return 1;
       // natural sorting through split numeric strings and default strings
       for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
        // find floats not starting with '0', string or 0 if not defined (Clint Priest)
        oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
        oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
        // handle numeric vs string comparison - number < string - (Kyle Adams)
        if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? -1 : 1;
        // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
        else if (typeof oFxNcL !== typeof oFyNcL) {
         oFxNcL += '';
         oFyNcL += '';
        }
        if (oFxNcL <= oFyNcL) return -1;
        if (oFxNcL >= oFyNcL) return 1;
       }
       return 0;
      }
    

3 个答案:

答案 0 :(得分:12)

说实话,我根本不知道你发布的功能是什么......

以下方法使用位置匹配来比较第一个字符的字符串。具有相同第一个字符的字符串会定期排序。

顺便说一下,没有测试空字符串。

function MySort(alphabet)
{
    return function(a, b) {
        var index_a = alphabet.indexOf(a[0]),
        index_b = alphabet.indexOf(b[0]);

        if (index_a === index_b) {
            // same first character, sort regular
            if (a < b) {
                return -1;
            } else if (a > b) {
                return 1;
            }
            return 0;
        } else {
            return index_a - index_b;
        }
    }
}

var items = ['asd','sdf', 'dsdf', '1sadf', '*sdf', '!sdf', '@asdf', '_asd', '.sadf', '(sadf', ')sadf', '#sadf', '^asdf', '&asdf', '%asdf', '-sadf', '=sadf', '+sadf', '-sdf', 'sef'],
sorter = MySort('*!@_.()#^&%-=+01234567989abcdefghijklmnopqrstuvwxyz');

console.log(items.sort(sorter));

输出:

["*sdf", "!sdf", "@asdf", "_asd", ".sadf", "(sadf", ")sadf", "#sadf", "^asdf", 
 "&asdf", "%asdf", "-sadf", "-sdf", "=sadf", "+sadf", "1sadf", 
 "asd", "dsdf", "sdf", "sef"]

答案 1 :(得分:1)

这也可能起作用:

function sortArray(a, b) {
  const digitRegex = /^\d/;
  const alphabetRegex = /^[a-zA-Z]/;
  const symbolRegex = /^[^\w\s]/;
  
  const scoreA =  symbolRegex.test(a) * 1 || digitRegex.test(a) * 10 || alphabetRegex.test(a) * 100;
  const scoreB =  symbolRegex.test(b) * 1 || digitRegex.test(b) * 10 || alphabetRegex.test(b) * 100;
  
  if (scoreA !== scoreB) {
    return scoreA - scoreB;
  }
  
  if (a < b) {
    return -1;
  } else if (a > b) {
    return 1;
  }
  
  return 0;
}

const a = ['def', '%rec', '456', '^we', '123', 'abc'].sort(sortArray);

console.log(a);

答案 2 :(得分:1)

两个简单的解决方案:

使用 Intl.Collat​​or

myArray.sort(Intl.Collator().compare)

使用 localeCompare

myArray.sort((a, b) => a.localeCompare(b))

Intl.Collat​​or 更高效