学习sort()方法的比较函数localeCompare()

186 阅读3分钟

今天学习sort(),感觉有好大的学问,建议仔细看看mdn文档)

今天我们来谈谈sort()方法的比较函数localeCompare()

我们都知道在 JavaScript 中,sort() 方法用于对数组进行排序。它可以接受一个可选的比较函数作为参数,该函数用于指定元素排序的顺序。sort() 方法将会根据比较函数的返回值来确定元素的排序位置。

  • 如果 compareFunction(a, b) 返回一个小于 0 的值,那么 a 会被排在 b 之前(被认为 a 小于 b)。
  • 如果 compareFunction(a, b) 返回一个大于 0 的值,那么 b 会被排在 a 之前(被认为 a 大于 b)。
  • 如果 compareFunction(a, b) 返回 0,那么 a 和 b 的相对位置不变。

那么这个比较函数compareFunction是什么呢?

对于 sort() 方法来说,没有传递比较函数参数时,默认会将元素转换为字符串并按字母顺序进行排序,也就是sort()默认的比较方法String.prototype.localeCompare

语法:string.localeCompare(compareString[, locales[, options]])

  • compareString:要与当前字符串进行比较的字符串。
  • locales:一个字符串或字符串数组,用于指定在比较过程中要使用的语言或区域设置。默认值是当前宿主环境的默认值。
  • options:一个可选的对象,包含比较选项。

localeCompare() 方法返回一个数字,表示两个字符串之间的比较结果。返回值可能是负数、0 或正数,具体取决于字符串的排序顺序。

但是请注意,这种默认的字母顺序排序可能不是你所预期的,特别是当对数字进行排序时,请谨慎使用默认的排序方法。为了达到期望的排序结果,建议使用比较函数来明确指定排序规则。

我们来看一道例子

let arr=['sswt','ssjx','kjk','aa','kal','bb']
arr.sort() //--->  ['aa', 'bb', 'kal', 'kjk', 'ssjx', 'sswt']
arr.sort((a,b)=>a.localeCompare(b)) //--->  ['aa', 'bb', 'kal', 'kjk', 'ssjx', 'sswt']

可以看到结果一致,那它是怎么排序的呢?我们来打印一下a b

let arr=['sswt','ssjx','kjk','aa','kal','bb']
arr.sort((a,b)=>console.log(a,b)) 
//-->   bb aa
        kal bb
        kjk kal
        ssjx kjk
        sswt ssjx
        
//--> 结果是:['aa', 'bb', 'kal', 'kjk', 'ssjx', 'sswt']
// 可以看到它比较了五轮,两两比较,每轮按照字母表升序排序的方法,如果第一个字母相同则比较下一个字母。
//第一轮在六个找到 <次小,最小>,在第一轮比较完成,最小排在数组第一位,次小就变成最小,往返循环比较。
 
 //打印localeCompare函数结果。
 arr.sort((a,b)=>console.log(a.localeCompare(b)))
 //--> 打印出五次1,代表升序。
 

如果反过来呢

arr.sort((a,b)=>console.log(b,a))
//-->   sswt ssjx
        ssjx kjk
        kjk kal
        kal bb
        bb aa

//结果是:['sswt', 'ssjx', 'kjk', 'kal', 'bb', 'aa']
// 可以看到同样比较五次,两两比较,每轮按照字母表降序排序的方法,
//不过<b, a>变成了<最大,次大>,在第一轮比较完成,最大排在数组第一位,次大就变成最大,往返循环比较。

//打印localeCompare函数结果。
arr.sort((a,b)=>console.log(b.localeCompare(a)))
//--> 打印出五次-1,代表降序。

console.log(a.localeCompare(b))能打印出0就意味着元素相同了。

如果自定义比较函数呢?

看个例子

const arr = [
  'peach',
  'straw',
  'apple',
  'spork'
];

// 只比较s1,s2字符串的第一个字母,根据ascii值
const stableSorting = (s1, s2) => {
  if (s1[0] < s2[0]) return -1; // s1排在s2前
  return 1; // s1排在s2后
};
//每轮要比较的s1,s2
// straw peach
// apple straw
// spork apple

arr.sort(stableSorting)
// ["apple", "peach", "straw", "spork"]

// 可以看到,当第一个字母一致时,就会按照原来的顺序排序,因为我们的比较函数只比较第一个字母。

可以使用localeCompare() 方法来实现中文按照拼音排序,方法相当简单

var array = ['白鸽', '麻雀', '大象', '狗', '猫', "鸡"];
array = array.sort(function compareFunction(item1, item2) {
    return item1.localeCompare(item2);
});
console.log(array);
//---> ['白鸽', '大象', '狗', '鸡', '麻雀', '猫']