Javascript: 如何按数字、字母和符号对数组进行排序?

5
我正在尝试使用Javascript对这个数组进行排序。
arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"]; 

我希望数组的显示方式是这样的:
["3", "4", "10", "23", "42", "63", "ABC", "adidas", "ax", "ba", "mof", ")", "["]

考虑到符号 “)” 和 “[”。

我希望数组的排序顺序如下:

  1. 从小到大排列数字
  2. 然后是单词,不区分首字母大小写
  3. 最后是符号

我知道我必须使用 sort(),但问题是我无法对包含符号的数组进行排序,我遇到了这个问题。

我正在使用以下代码在 HTML 中显示数组和排序后的数组:

var arr, text, larr, i; 
arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"]; 
larr = arr.length;

text = "<ul>";
for (i = 0; i < larr; i++) {
  text += "<li>" + arr[i] + "</li>";
}
text += "</ul>";

document.getElementById("arrayin").innerHTML = text;

console.log(arr);

var arror,textor, larror, j;

arror = arr.sort();

larror = arror.length;

textor = "<ul>";
for (j = 0; j < larror; j++) {
  textor += "<li>" + arror[j] + "</li>";
}
textor += "</ul>";

console.log(arror);

document.getElementById("Oarray").innerHTML = textor;

我的最后一个问题是如何对数字、字母和符号的数组进行排序


你需要创建一个自定义排序函数,并将其作为 arr.sort(sortFunction); 传递。该函数有两个参数。在排序函数内部,你需要首先比较这两个参数是否都是类似数字的类型,如果是,则返回它们比较的适当整数值(将类似数字的字符串作为数字进行比较),如果不是,则将它们都转换为大写字母并按字典顺序进行比较。 - Sunny Patel
5个回答

4

正如你所猜测的,你需要使用sort方法并传入比较函数。为了得到你想要的顺序,以下检查将起作用。 在jsfiddle上的完整工作示例https://jsfiddle.net/aczhyk8j/1/

function compare(a, b) {
  // check for numberhood
  const numA = !isNaN(a);
  const numB = !isNaN(b);

  if (numA && numB) {
    return Number(a) - Number(b);
  }

  if (numA) return -1;
  if (numB) return 1;

  // check for wordhood
  const wordA = /^[a-zA-Z]+$/.test(a);
  const wordB = /^[a-zA-Z]+$/.test(b);

  if (wordA && wordB) {
    return a.localeCompare(b);
  }

  if (wordA) return -1;
  if (wordB) return 1;

  return 1; // or whatever logic to sort within non-alphanumeric values
}

// Now, use it in your sort method call.
let arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"];

arr.sort(compare);
console.log(arr);


中文字符被视为特殊符号,您是否会将其视为字母进行更改? - kushal
请问您如何修改上面的代码,以便获得以下格式的输出:[ "3", "4", "10", "23", "42", "63", "A", "B", C", "M", "a", "b", "c", "m", Adidas", "ax", "ba", "mof", ")", "[" ]。我的意思是先输出数字,然后是从A到Z的字母,最后是单词和符号。非常感谢! - Itsme

3
使用自定义的sort()函数,您可以实现您想要的功能。
这并不容易,可能需要一些“hacky”方法来将符号与普通字符分开。 我使用了这种“hacky”方法,但也许有人可以用正则表达式或其他方法帮助。
我的hack是拥有一个可能的符号数组,然后在sort()内部,当正在比较的其中一个项等于其中一个符号时,临时将其更改为字符串"zzzzzzz",这可能会使它进入最后一个位置,因为排序是从"a""z"sort()函数需要返回10-1,所以这就是自定义compare()函数所做的事情。它首先看看被比较的单词是否是有效的数字,如果是,则比较哪个先出现。然后如果不是数字,将其作为大写字符串进行比较,因为您说大小写无关紧要(使用正常的字典排序)
测试下面的代码,看看它是否符合您的需求。

var arr = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC"]
var symbols = "()[]{}!@#$%¨&*-_=+".split("");

function compare(array){
  array.sort((a,b) => {
  
    if (symbols.indexOf(a) > -1) a = "zzzzzzz"    
    if (symbols.indexOf(b) > -1) b = "zzzzzzz"

    if (!isNaN(Number(a)) && !isNaN(Number(b))){      
        if (Number(a) > Number(b)){
          return 1;
        }else if(Number(a) < Number(b)){
          return -1;
        }else{
          return 0;
        }
        
    }else{         
      if (a.toUpperCase() > b.toUpperCase()){
          return 1;
      }else if(a.toUpperCase() < b.toUpperCase()){
        return -1;
      }else{
        return 0;
      }      
    }    
  })
  return array;
}

console.log(compare(arr))


3

我在这个自定义比较函数中使用了sort。请注意,比较器应该返回一个正数,如果a应该在b之前,返回一个负数,如果b应该在a之前,返回0表示元素在排序下相等。

let array = ["ax", "mof", "4", "63", "42", "3", "10", "[", "23", "adidas", "ba", ")", "ABC", "abc"];

array.sort((a, b) => {
  const aStr = String(a).toLowerCase();
  const bStr = String(b).toLowerCase();

  // Alphanumeric elements always come before non-alphanumeric elements
  const aIsAlphanumeric = isAlphanumeric(aStr);
  const bIsAlphanumeric = isAlphanumeric(bStr);
  if (aIsAlphanumeric && !bIsAlphanumeric) {
    return -1;
  } else if (bIsAlphanumeric && !aIsAlphanumeric) {
    return 1;
  }

  // Numerical elements always come before alphabetic elements
  const aNum = Number(a);
  const bNum = Number(b);
  // If both are numerical, sort in the usual fashion (smaller goes first)
  if (aNum && bNum) {
    return aNum - bNum;
    // If a is numerical but b isn't, put a first.
  } else if (aNum) {
    return -1;
    // If b is numerical but a isn't, put b first.
  } else if (bNum) {
    return 1;
  }

  // In all other cases, default to usual sort order.
  return aStr.localeCompare(bStr);
});

console.log(array);

function isAlphanumeric(str) {
  var code, i, len;

  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);
    if (!(code > 47 && code < 58) && // numeric (0-9)
      !(code > 64 && code < 91) && // upper alpha (A-Z)
      !(code > 96 && code < 123)) { // lower alpha (a-z)
      return false;
    }
  }

  return true;
}

注意: isAlphanumeric 函数是从这个答案中获取的。


0

0
我使用这个工具来简化复杂的多重比较排序。非常容易适应,对于任何查看这个问题的人来说可能都很有用。

const strings = [
    'Match but long text should be sorted down',
    'This would go even further below',
    'And this even more since it\'s longer than we like',
    'Also below',
    '0 goes way down',
    '1 below it',
    '$ all the way down',
    'á and match for top',
    'á should go below ma-tches',
    'Á this below á',
    'Zee match for second row'

];

const matchText = 'match';
const sortBelowLen = 40;

// List of comparison functions.  Should return -1 if a goes before b, 1 if after, 0 if equal.
const sortTests = [
    // Contains matchText (ignore case)
    (a, b) => sortTest(a, b, (x) => x.toLowerCase().indexOf(matchText) >= 0),
    // Starts with a letter (including Latin alphabets)
    (a, b) => sortTest(a, b, (x) => /^[a-z\u00C0-\u00F6\u00F8-\u017E]/i.test(x)),
    // Starts with a number
    (a, b) => sortTest(a, b, (x) => /^\d/i.test(x)),
    // Is shorter than sortBelowLen
    (a, b) => sortTest(a, b, (x) => x.length < sortBelowLen),
    // Finally, sort by the usual order, but localized (ignore case)
    (a, b) => a.toLowerCase().localeCompare(b.toLowerCase()),
];
// Calls boolean testFun with a and b, returns the proper value for sort():
// -1 if a only 'a' gives true with testFun, 1 if b, 0 if both
const sortTest = (a, b, testFun) => (testFun(b) ? 1 : 0) - (testFun(a) ? 1 : 0);

// Runs comparisons in sortTests until a sorting difference is found
const multiSort = (a, b) => {
    for (const comparison of sortTests) {
    //    console.log(a, b, comparison(a, b)); 
       const result = comparison(a, b);
       if (result !== 0) { return result; }
    } 
    return 0;
}
strings.sort(multiSort);
console.log(strings);
console.log('Vs. default sort:')
strings.sort();
console.log(strings)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接