【问题标题】:Sorting array of string but numbers last排序字符串数组,但数字最后
【发布时间】:2019-11-13 00:49:05
【问题描述】:

我需要对我的数组进行排序。我想在 alfa 之后看到字符串开始/包含数字。

作为:

['ip', 'email', '0email', 'em0ail' ,1001, '23name', 'name', 'address']

应该是:

['address', 'email', 'em0ail', 'ip', 'name', '0email', 1001, '23name']

所以0 应该在z 之后

columns.sort((a, b) => {
      const x = a.toString();
      const y = b.toString();
      if (x < y) {
        return -1;
      }
      if (x > y) {
        return 1;
      }
      return 0;
    });

首先返回数字

我应该如何处理这种情况?我必须遍历整个字符串吗?

【问题讨论】:

  • 将原始数组拆分为两个数组:startWithLetter 和 startWithNumber。将它们单独排序并根据需要合并数组。
  • @EliasSoares 似乎工作量太大,而不仅仅是在排序期间检查每个项目的开始。

标签: javascript arrays sorting


【解决方案1】:

我必须遍历整个字符串吗?

如果您只是基于字符串中的第一个字符(如您所见,em0ail 与字符串一起排序),则不会。只需检查字符串是否以数字或非数字开头,如果一个有数字而另一个没有,则返回适当的 1 或 -1 以将非数字放在第一位;如果它们都以数字开头或不以数字开头,则返回 localeCompare 的结果。

(对于数字,我们可以转换为字符串。)

const columns = ['ip', 'email', '0email', 'em0ail' ,1001, '23name', 'name', 'address'];

function startsWithDigit(v) {
    const ch = v[0];
    return ch >= "0" && ch <= "9";
}

columns.sort((a, b) => {
    a = String(a);
    b = String(b);
    adigit = startsWithDigit(a);
    bdigit = startsWithDigit(b);
    if (adigit == bdigit) {
        return a.localeCompare(b);
    } else if (adigit) {
        return 1;
    } else {
        return -1;
    }
});

console.log(columns);

【讨论】:

  • startsWithDigit 实现的替代方法是执行parseInt 并检查结果是否为NaN。开始写一个答案,这基本上是唯一的主要区别,但现在不需要,所以我把它作为评论。
  • @VLAZ - 这样会更简单,不是吗?好主意。
  • 嗯,我想到了parseInt 的一个(潜在)问题——开头有空格。字符串" 123abc" 将被解析为123。我不知道 OP 是否希望是这种情况(空格被忽略)。
  • 这很公平。 parseInt 是一种可能的方法,但如果不知道这里的要求,很难说它是否正确。不过,这似乎有点不一致,因为 " a""b"" 1""2" 的排序方式不同。
【解决方案2】:

<!DOCTYPE html>
<html>
<head>

</head>

<body>


<script>
var columns=['ip', 'email', '0email', 'em0ail' ,1001, '23name', 'name', 'address'];
function Turn(CharZ){
	//Make 0~9 biger then a-z and A-Z
	if(CharZ<'9'.charCodeAt()){
		return CharZ+'Z'.charCodeAt();
	}
	return CharZ;
}
columns.sort((a, b) => {
	var x = a.toString();
	var y = b.toString();
	var Lx=x.length;
	var Ly=y.length;
	var MinL=Math.min(Lx, Ly);
	for (var i = 0; i < MinL; i++) {
		if(Turn(x.charCodeAt(i))-Turn(y.charCodeAt(i))>0){
			return 1;
		}else if(Turn(x.charCodeAt(i))-Turn(y.charCodeAt(i))<0){
			return -1;
		}
		
		
	}
	//if front all equals  but length not same mean there is remain
	if (Lx > Ly) {
		return 1;
	}
	if (Lx < Ly) {
		return -1;
	}
	return 0;
});
document.body.innerHTML = columns;

</script>

</body>
</html>

希望有帮助

【讨论】:

    猜你喜欢
    • 2016-10-07
    • 2014-07-11
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多