JavaScript中Array.prototype.sort()的詳解


摘抄來源:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

sort() 方法對數組的元素做原地的排序,並返回這個數組。 sort 排序可能是不穩定的。默認按照字符串的Unicode碼位點(code point)排序。

語法

arr.sort([compareFunction])

參數

compareFunction可選。用來指定按某種順序進行排列的函數。如果省略,元素按照轉換為的字符串的諸個字符的Unicode位點進行排序。

描述

如果沒有指明 compareFunction ,那么元素會按照轉換為的字符串的諸個字符的Unicode位點進行排序。例如 "Banana" 會被排列到 "cherry" 之前。數字比大小時,9 出現在 80 之前,但這里比較時數字會先被轉換為字符串,所以 "80" 比 "9" 要靠前。

var fruit = ['cherries', 'apples', 'bananas'];
fruit.sort(); // ['apples', 'bananas', 'cherries']

var scores = [1, 10, 2, 21]; 
scores.sort(); // [1, 10, 2, 21]
// Watch out that 10 comes before 2,
// because '10' comes before '2' in Unicode code point order.

var things = ['word', 'Word', '1 Word', '2 Words'];
things.sort(); // ['1 Word', '2 Words', 'Word', 'word']
// In Unicode, numbers come before upper case letters,
// which come before lower case letters.

 

如果指明了 compareFunction ,那么數組會按照調用該函數的返回值排序。記 a 和 b 是兩個將要被比較的元素:

  • 如果 compareFunction(a, b) 小於 0 ,那么 a 會被排列到 b 之前;
  • 如果 compareFunction(a, b) 等於 0 , a 和 b 的相對位置不變。備注: ECMAScript 標准並不保證這一行為,而且也不是所有瀏覽器都會遵守(例如 Mozilla 在 2003 年之前的版本);
  • 如果 compareFunction(a, b) 大於 0 , b 會被排列到 a 之前。
  • compareFunction(a, b) 必須總是對相同的輸入返回相同的比較結果,否則排序的結果將是不確定的。

所以,比較函數格式如下:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

希望比較數字而非字符串,比較函數可以簡單的以 a 減 b,如下的函數將會將數組升序排列

function compareNumbers(a, b) {
  return a - b;
}

sort 方法可以使用 函數表達式 方便地書寫:

var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers);

// [1, 2, 3, 4, 5]

對象可以按照某個屬性排序:

var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
];

items.sort(function (a, b) {
  if (a.value > b.value) {
    return 1;
  }
  if (a.value < b.value) {
    return -1;
  }
  // a 必須等於 b
  return 0;
});

示例

創建、顯示及排序數組

下述示例創建了四個數組,並展示原數組。之后對數組進行排序。對比了數字數組分別指定與不指定比較函數的結果。

var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b)
{
  return a - b;
}

console.log('stringArray:', stringArray.join());
console.log('Sorted:', stringArray.sort());

console.log('numberArray:', numberArray.join());
console.log('Sorted without a compare function:', numberArray.sort());
console.log('Sorted with compareNumbers:', numberArray.sort(compareNumbers));

console.log('numericStringArray:', numericStringArray.join());
console.log('Sorted without a compare function:', numericStringArray.sort());
console.log('Sorted with compareNumbers:', numericStringArray.sort(compareNumbers));

console.log('mixedNumericArray:', mixedNumericArray.join());
console.log('Sorted without a compare function:', mixedNumericArray.sort());
console.log('Sorted with compareNumbers:', mixedNumericArray.sort(compareNumbers));

 

該示例的返回結果如下。輸出顯示,當使用比較函數后,數字數組會按照數字大小排序。

stringArray: Blue,Humpback,Beluga
Sorted: Beluga,Blue,Humpback

numberArray: 40,1,5,200
Sorted without a compare function: 1,200,40,5
Sorted with compareNumbers: 1,5,40,200

numericStringArray: 80,9,700
Sorted without a compare function: 700,80,9
Sorted with compareNumbers: 9,80,700

mixedNumericArray: 80,9,700,40,1,5,200
Sorted without a compare function: 1,200,40,5,700,80,9
Sorted with compareNumbers: 1,5,9,40,80,200,700

對非 ASCII 字符排序

當排序非 ASCII 字符的字符串(如包含類似 e, é, è, a, ä 等字符的字符串)。一些非英語語言的字符串需要使用 String.localeCompare。這個函數可以將函數排序到正確的順序。

var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];
items.sort(function (a, b) {
  return a.localeCompare(b);
});

// items is ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']

使用映射改善排序

compareFunction 可能需要對元素做多次映射以實現排序,尤其當 compareFunction 較為復雜,且元素較多的時候,某些 compareFunction 可能會導致很高的負載。使用 map 輔助排序將會是一個好主意。基本思想是首先將數組中的每個元素比較的實際值取出來,排序后再將數組恢復。

// 需要被排序的數組
var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];

// 對需要排序的數字和位置的臨時存儲
var mapped = list.map(function(el, i) {
  return { index: i, value: el.toLowerCase() };
})

// 按照多個值排序數組
mapped.sort(function(a, b) {
  return +(a.value > b.value) || +(a.value === b.value) - 1;
});

// 根據索引得到排序的結果
var result = mapped.map(function(el){
  return list[el.index];
});

規范

Specification Status Comment
ECMAScript 1st Edition (ECMA-262) Standard Initial definition.
ECMAScript 5.1 (ECMA-262)
Array.prototype.sort
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
Array.prototype.sort
Standard  

瀏覽器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 1.0 1.0 (1.7 or earlier) 5.5 (Yes) (Yes)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM