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
1.1k views
in Technique[技术] by (71.8m points)

arrays - Sorting in Javascript with special characters

I have an array with the following values

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

and i want to sort it in javascript in the following way in to three parts.

  1. word starting from special character
  2. word starting from digit
  3. word starting from alphabets.

So this should be the sequence of the sorted array.

EDIT: Here's a function that I've been experimenting with:

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, '$1').replace(/$/, '').replace(/^/, '').split(''),
  yN = y.replace(re, '$1').replace(/$/, '').replace(/^/, '').split(''),
   // 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;
  }
See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

To be honest, I have no idea what your posted function does ... at all.

The following approach compares strings on their first character, using positional occurrence. Strings with the same first character are sorted regularly.

Btw, didn't test for empty strings.

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

Output:

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

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

1.4m articles

1.4m replys

5 comments

57.0k users

...