整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

如何用JavaScript排序包含字母的数字字符串

如何用JavaScript排序包含字母的数字字符串

日常开发中,我们经常会遇到需要对带字母的数字字符串进行排序的场景。比如,在电商网站中,我们需要对包含商品编号的字符串进行排序,这些编号可能既有数字部分又有字母部分。今天,我就来给大家分享一个简单易懂的方法,用JavaScript实现这样的排序。

需求场景

想象一下,我们在开发一个库存管理系统,需要对一系列商品编号进行排序。这些商品编号是由数字和字母组成的,例如 12A, 2A, B3, 12B, C1。如果我们按照默认的字符串排序方式,结果往往不是我们想要的。这时候,我们就需要一种能正确处理这种带字母数字字符串的排序方法。

方法一:使用localeCompare

JavaScript中的localeCompare方法可以帮助我们实现这一需求。它不仅可以比较字符串,还能根据需要进行数字排序。下面是具体的实现代码:

const items=[
  '12A',
  '2A',
  'B3',
  '12B',
  'C1',
  'A21',
  '21B',
  'B19',
  'C3',
  'D2'
];

const sortedItems=items.sort((a, b)=> {
  return a.localeCompare(b, undefined, {
    numeric: true,
    sensitivity: 'base'
  });
});

console.log(sortedItems);

在这个例子中,我们创建了一个包含商品编号的数组items。然后,我们使用sort方法对数组进行排序,并在排序函数中调用localeCompare方法。设置numerictrue可以使数字部分按照数值大小排序,而sensitivity设置为base则忽略大小写进行比较。

排序后的结果是:

[ '2A',  '12A', '12B',
  '21B', 'A21', 'B3',
  'B19', 'C1',  'C3',
  'D2']

方法二:使用Intl.Collator

另一种方法是使用Intl.Collator构造函数创建一个比较器实例,它同样能够对字符串进行自然排序。下面是具体实现:

const items=[
  '12A',
  '2A',
  'B3',
  '12B',
  'C1',
  'A21',
  '21B',
  'B19',
  'C3',
  'D2'
];

const collator=new Intl.Collator(undefined, {
  numeric: true,
  sensitivity: 'base'
});

const sortedItems=items.sort((a, b)=> {
  return collator.compare(a, b);
});

console.log(sortedItems);

这个方法和localeCompare类似,只是我们通过Intl.Collator创建了一个比较器实例,并使用它的compare方法来进行排序。

排序后的结果与之前相同:

[
  '2A',  '12A', '12B',
  '21B', 'A21', 'B3',
  'B19', 'C1',  'C3',
  'D2'
]

结束

通过使用localeCompareIntl.Collator方法,我们可以轻松地对带字母的数字字符串进行自然排序。这不仅在电商网站的商品编号排序中非常实用,在处理任何包含数字和字母的字符串排序时都能派上用场。

i列表排序

<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
#ul1 {background:green;}
#ul2 {background:yellow;}
</style>
<script>
window.onload=function (){
    var oUl1=document.getElementById('ul1');
    var oBtn=document.getElementById('btn1');

    oBtn.onclick=function (){
    var aLi=oUl1.getElementsByTagName('li');
    //aLi.sort(); 此方法不可行,因为aLi是元素集合,不是数组,sort()只能用于数组排序
    var arr=[];

    for(var i=0;i<aLi.length;i++){
    arr[i]=aLi[i]; //aLi元素集合转换为数组
    }

    arr.sort(function (li1, li2){ //自定义排序函数
    var n1=parseInt(li1.innerHTML); //将字符串转换为整数
    var n2=parseInt(li2.innerHTML);
    return n1-n2;
    });
    //alert(arr[0].innerHTML);
    for(var i=0;i<arr.length;i++){
    //alert('该把'+arr[i].innerHTML+'插入到最后');
    oUl1.appendChild(arr[i]);
    }
    };
};
</script>
</head>
<body>
<input id="btn1" type="button" value="排序" />
<ul id="ul1">
<li>34</li>
<li>25</li>
<li>9</li>
<li>88</li>
<li>54</li>
</ul>
</body>
</html>

appendChild()方法理解:

target.appendChild(newnode)

1.先把元素从原有父级上删掉

2.添加到原有的父级元素下, 起到了移动子元素的作用。

值类型排序

console.log([5,6,2,3].sort())

字符串类型的数组排序

console.log(['中国01#', '中国02#', '中国023#', '中国10#', '中国1#', '中国2#', '中国11#', '中国20#'].sort())

虽然排序了,但是按照ASCII排序的,中间是数字,这样的方式显然不是我们需要的

熟悉sort方法的同学知道sort支持传入比较器,是的我们可以自定义比较器传入,这样想要什么的排序都可以实现,但是复杂比较器实现起来也有一定的工作量和难度的,因此我们要介绍的主角出现了,它就是Intl.Collator

Intl.Collator比较器

console.log(['中国01#', '中国02#', '中国023#', '中国10#', '中国1#', '中国2#', '中国11#', '中国20#']
     .sort(new Intl.Collator('zh-CN').compare))

默认比较器排序的结果和sort默认的比较器排序一样,但是我们可以给比较传入一个排序的options参数,如是否应使用数字对照,使得“1”<“2”<“10”。可能的值为 true 和 false;默认值为 false

console.log(['中国01#', '中国02#', '中国023#', '中国10#', '中国1#', '中国2#', '中国11#', '中国20#']
    .sort(new Intl.Collator('zh-CN', { numeric: true }).compare))

此时排序的就是按照中文数字的方式排序了

补:options 可选

包含一些或所有的以下属性的对象:

localeMatcher

使用的区域匹配算法。可能的值为:"lookup" 和 "best fit";默认值为 "best fit"。参见 Intl 页面以了解此选项的详细信息。

usage

比较是用于排序还是用于搜索匹配的字符串。可能的值为 "sort" 和 "search";默认值为 "sort"。

sensitivity

字符串中的哪些差异应导致结果值为非零。可能的值为:

  • "base":只有字母不同的字符串比较不相等。例如:a ≠ b、a=á、a=A。
  • "accent":只有不同的基本字母或重音符号和其他变音符号的字符串比较为不相等。例如:a ≠ b、a ≠ á、a=A。
  • "case":只有不同的基本字母或大小写的字符串比较不相等。例如:a ≠ b、a=á、a ≠ A。
  • "variant":字符串的字母、重音和其他变音符号,或不同大小写比较不相等。也可以考虑其他差异。例如:a ≠ b、a ≠ á、a ≠ A。

"sort" 用法(usage)的默认值为 "variant"。"search" 用法则取决于区域。

ignorePunctuation

是否应忽略标点。可能的值为 true 和 false;默认值为 false。

numeric

是否应使用数字对照,使得“1”<“2”<“10”。可能的值为 true 和 false;默认值为 false。此选项也可以通过 Unicode 扩展键 kn 设置;当两者同时设置时,options 属性的优先级更高。

caseFirst

是否应该首先根据大小写排序。可能的值为 "upper"、"lower" 和 "false"(使用区域的默认设置)。此选项也可以通过 Unicode 扩展键 kf 设置;当两者同时设置时,options 属性的优先级更高。

collation

一些区域的变体。可能的值包括:

  • big5han(汉语;在 Chrome 和 Edge 中不可用)
  • compat(阿拉伯语)
  • dict(僧伽罗语)
  • direct(已弃用,请勿使用)
  • ducet(不可用,请勿使用)
  • emoji(root)
  • eor(root)
  • gb2312(汉语;在 Chrome 和 Edge 中不可用)
  • phonebk(德语)
  • phonetic(林加拉语)
  • pinyin(汉语)
  • reformed(瑞典语;不需要明确指定,因为这是瑞典语的默认设置)
  • searchjl(韩语;请勿用于排序)
  • stroke(汉语)
  • trad
  • unihan(汉语、日语和韩语;在 Chrome 和 Edge 中不可用)
  • zhuyin(汉语)

此选项也可以通过 Unicode 扩展键 co 设置;当两者同时设置时,options 属性的优先级更高。