Array.prototype.sort()
Baseline
åºãå©ç¨å¯è½
ãã®æ©è½ã¯åºãå®è£ ããã¦ãããå¤ãã®ãã¼ã¸ã§ã³ã®ç«¯æ«ããã©ã¦ã¶ã¼ã§åä½ãã¾ãã2015å¹´7æä»¥éããã¹ã¦ã®ãã©ã¦ã¶ã¼ã§å©ç¨å¯è½ã§ãã
sort() 㯠Array ã®ã¡ã½ããã§ãé
åã®è¦ç´ ããã®å ´ (in-place) ã§ã½ã¼ãããã½ã¼ããããåãé
åã®åç
§ãè¿ãã¾ããæ¢å®ã®ã½ã¼ãé ã¯æé ã§ãè¦ç´ ãæååã«å¤æãã¦ããã UTF-16 ã³ã¼ãåä½ã®å¤ã®ä¸¦ã³ã¨ãã¦æ¯è¼ãã¾ãã
ã½ã¼ãã®æéçã»ç©ºéçäºæ¸¬å¤ã¯å®è£ ã«ä¾åãããããä¿è¨¼ã¯ã§ãã¾ããã
å
ã®é
åã夿´ããã«é
åå
ã®è¦ç´ ãã½ã¼ãããã«ã¯ã toSorted() ã使ç¨ãã¦ãã ããã
試ãã¦ã¿ã¾ããã
const months = ["March", "Jan", "Feb", "Dec"];
months.sort();
console.log(months);
// äºæ³ãããçµæ: Array ["Dec", "Feb", "Jan", "March"]
const array = [1, 30, 4, 21, 100000];
array.sort();
console.log(array);
// äºæ³ãããçµæ: Array [1, 100000, 21, 30, 4]
æ§æ
sort()
sort(compareFn)
弿°
compareFnçç¥å¯-
è¦ç´ ã®é åºã決å®ãã颿°ããã®é¢æ°ã¯ã次ã®å¼æ°ã§å¼ã³åºããã¾ãã
a-
æ¯è¼ãã第ä¸è¦ç´ ã
undefinedã«ãªããã¨ã¯ããã¾ããã b-
æ¯è¼ãã第äºè¦ç´ ã
undefinedã«ãªããã¨ã¯ããã¾ããã
ããã¯ã以ä¸ã®æ°å¤ãè¿ãã¾ãã
- è² ã®å¤ã¯ã
aãbããåã«æ¥ãã¹ãã§ãããã¨ã示ãã¾ãã - æ£ã®å¤ã¯ã
aãbã®å¾ã«æ¥ãã¹ãã§ãããã¨ã示ãã¾ãã - 0 ã¾ãã¯
NaNã¯ãaã¨bãçããã¨ã¿ãªããããã¨ã示ãã¾ãã
ãããè¦ããã«ã¯ã
(a, b) => a - bã¯æ°å¤ãæé ã§ã½ã¼ããããã¨ãè¦ãã¦ããã¦ãã ãããçç¥ããå ´åãé åã®è¦ç´ ã¯æååã«å¤æãããããããã®æåã® Unicode ã³ã¼ããã¤ã³ãã®å¤ã«å¾ã£ã¦ã½ã¼ãããã¾ãã
è¿å¤
ã½ã¼ããããå ã®é åã¸ã®åç §ã§ãããªããé åã¯ãã®å ´ã§ã½ã¼ããããã³ãã¼ã¯ä½æããã¾ããã
解説
compareFn ãä¸ããããªãã£ãå ´åãundefined 以å¤ã®ãã¹ã¦ã®é
åè¦ç´ ã¯æååã«å¤æãããæååã UTF-16 ã³ã¼ãåä½é ã§ã½ã¼ãããã¾ããä¾ãã°ã"banana" 㯠"cherry" ã®åã«æ¥ã¾ããæ°å¤ã®ã½ã¼ãã§ã¯ã9 ã 80 ã®åã«æ¥ã¾ãããæ°å¤ã¯æååã«å¤æããããããUnicode é ã§ "80" ã "9" ã®åã«æ¥ã¾ããundefined ã®è¦ç´ ã¯ãã¹ã¦ãé
åã®æ«å°¾ã«ä¸¦ã¹ããã¾ãã
sort() ã¡ã½ããã¯ç©ºã®ã¹ããããä¿æãã¾ããçé
åã®å ´åã空ã®ã¹ãããã¯é
åã®æ«å°¾ã«ç§»åããã常ã«ãã¹ã¦ã® undefined ã®å¾ã«ç½®ããã¾ãã
ã¡ã¢:
UTF-16 ã§ã¯ã\uFFFF ãè¶
ãã Unicode æå㯠2 ã¤ã®ãµãã²ã¼ãã³ã¼ãåä½ã«ã¨ã³ã³ã¼ãããã\uD800 - \uDFFF ã®ç¯å²ã«ãªãã¾ããããããã®ã³ã¼ãåä½ã®å¤ã¯æ¯è¼ã§ã¯å¥ã
ã«æ±ããã¾ãããããã£ã¦ã\uD855\uDE51 ã¨ãããµãã²ã¼ããã¢ã§å½¢æãããæåã¯ã\uFF3A ã®æåãããåã«ä¸¦ã¹ããã¾ãã
compareFn ãä¸ããããå ´åãundefined 以å¤ã®ãã¹ã¦ã®é
åè¦ç´ ã¯æ¯è¼é¢æ°ã®è¿å¤ã«åºã¥ãã½ã¼ãããã¾ãï¼undefined ã®è¦ç´ ã¯ãã¹ã¦ãcompareFn ãå¼ã³åºããã¨ãªãé
åã®æ«å°¾ã¸ä¸¦ã¹ããã¾ãï¼ã
compareFn(a, b) ã®è¿å¤ |
ã½ã¼ãé |
|---|---|
| > 0 | a ã b ã®å¾ã«ä¸¦ã¹ãï¼ä¾ãã° [b, a]ï¼ |
| < 0 | a ã b ã®åã«ä¸¦ã¹ãï¼ä¾ãã° [a, b]ï¼ |
| === 0 | a 㨠b ã®å
ã®é åºãç¶æãã |
ãã£ã¦ãæ¯è¼é¢æ°ã¯ä»¥ä¸ã®ãããªå½¢å¼ããã¡ã¾ãã
function compareFn(a, b) {
if (ããé åºã®åºæºã«ãã㦠a 㯠b ããå°ãã) {
return -1;
} else if (ãã®é åºã®åºæºã«ãã㦠a 㯠b ãã大ãã) {
return 1;
}
// a 㯠b ã¨çãã
return 0;
}
ããæ£å¼ã«ã¯ãé©åãªã½ã¼ãåä½ãä¿è¨¼ããããã«ãæ¯è¼é¢æ°ã¯ä»¥ä¸ã®è¦ä»¶ãæºãããã¨ãæ±ãããã¾ãã
- ç¡å®³: æ¯è¼é¢æ°ã¯æ¯è¼ããããªãã¸ã§ã¯ããå¤é¨ã®ç¶æ ã夿´ãã¾ãããï¼ããã¯éè¦ã§ããæ¯è¼é¢æ°ããã¤ãã©ã®ããã«å¼ã³åºããããã¯ä¿è¨¼ããã¦ããªãã®ã§ãç¹å®ã®å¼ã³åºããå¤é¨ã«è¦ããå½±é¿ãåã¼ãã¦ã¯ããã¾ããï¼ã
- å®å®ç: æ¯è¼é¢æ°ã¯ãåãçµã®å ¥åã«å¯¾ãã¦å¸¸ã«åãçµæãè¿ãã¾ãã
- åå°ç:
compareFn(a, a) === 0ã¨ãªãã¾ãã - å対称ç:
compareFn(a, b)ã¨compareFn(b, a)ã¯ã¨ãã«0ã§ããããéã®ç¬¦å·ã§ãªããã°ãªãã¾ããã - æ¨ç§»ç:
compareFn(a, b)ã¨compareFn(b, c)ãã¨ãã«æ£ã0ãè² ã®ããããã§ããã°ãcompareFn(a, c)ã¯åã® 2 ã¤ã¨åã符å·ã«ãªãã¾ãã
ä¸è¨ã®å¶ç´ã«é©åããæ¯è¼é¢æ°ã¯ã常㫠1, 0, -1 ã®ãã¹ã¦ãè¿ããããããã¯ä¸è²«ã㦠0 ãè¿ããã¨ãã§ãã¾ããä¾ãã°ãæ¯è¼é¢æ°ã 1 㨠0 ã®ã¿ãè¿ãå ´åãããã㯠0 㨠-1 ã®ã¿ãè¿ãå ´åã¯ãåå¯¾ç§°æ§ ãå´©ããã®ã§ã確å®ã«ã½ã¼ããããã¨ã¯ã§ãã¾ããã常㫠0 ãè¿ãæ¯è¼é¢æ°ã§ã¯ãé
åã¯å
¨ã夿´ããã¾ããããããã§ãä¿¡é ¼ã§ãã¾ãã
æ¢å®ã®å奿¯è¼é¢æ°ã¯ãä¸è¨ã®å¶ç´ããã¹ã¦æºããã¦ãã¾ãã
æååã®ä»£ããã«æ°åãæ¯è¼ããå ´åãæ¯è¼é¢æ°ã¯åç´ã« a ãã b ãå¼ãã°ããã§ããããæ¬¡ã®ããã«æ¯è¼é¢æ°ãå®ç¾©ããã°æé ã«ä¸¦ã¹ããã¨ãã§ãã¾ãï¼Infinity ã NaN ããªããã°ã§ããï¼ã
function compareNumbers(a, b) {
return a - b;
}
sort() ã¡ã½ããã¯æ±ç¨çã§ãããã®ã¡ã½ãã㯠this å¤ã« length ããããã£ã¨æ´æ°ãã¼ã®ããããã£ããããã¨ã ããæå¾
ãã¾ããæååãé
å風ã§ãããæååã¯ä¸å¤ãªã®ã§ããã®ã¡ã½ãããé©ç¨ããã®ã«ã¯é©ãã¦ãã¾ããã
ä¾
>é åã®çæã表示ãã½ã¼ã
以ä¸ã®ä¾ã¯ 4 ã¤ã®é åãçæããå ã®é åã表示ããã®ã¡ã«ãã½ã¼ãããé åã表示ãã¾ããæ°å¤ã®é åã¯æ¯è¼é¢æ°ãªãã§ã½ã¼ããããã®ã¡ãæ¯è¼é¢æ°ããã§ã½ã¼ãããã¾ãã
const stringArray = ["Blue", "Humpback", "Beluga"];
const numberArray = [40, 1, 5, 200];
const numericStringArray = ["80", "9", "700"];
const mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];
function compareNumbers(a, b) {
return a - b;
}
stringArray.join(); // 'Blue,Humpback,Beluga'
stringArray.sort(); // ['Beluga', 'Blue', 'Humpback']
numberArray.join(); // '40,1,5,200'
numberArray.sort(); // [1, 200, 40, 5]
numberArray.sort(compareNumbers); // [1, 5, 40, 200]
numericStringArray.join(); // '80,9,700'
numericStringArray.sort(); // ['700', '80', '9']
numericStringArray.sort(compareNumbers); // ['9', '80', '700']
mixedNumericArray.join(); // '80,9,700,40,1,5,200'
mixedNumericArray.sort(); // [1, 200, 40, 5, '700', '80', '9']
mixedNumericArray.sort(compareNumbers); // [1, 5, '9', 40, '80', 200, '700']
ãªãã¸ã§ã¯ãã®é åã®ã½ã¼ã
ãªãã¸ã§ã¯ãã®é åã¯ãããããã£ã®å¤ãæ¯è¼ãããã¨ã§ä¸¦ã¹æ¿ãããã¨ãã§ãã¾ãã
const items = [
{ name: "Edward", value: 21 },
{ name: "Sharpe", value: 37 },
{ name: "And", value: 45 },
{ name: "The", value: -12 },
{ name: "Magnetic", value: 13 },
{ name: "Zeros", value: 37 },
];
// value ã«ããã½ã¼ã
items.sort((a, b) => a.value - b.value);
// name ã«ããã½ã¼ã
items.sort((a, b) => {
const nameA = a.name.toUpperCase(); // 大æåå°æåãç¡è¦
const nameB = b.name.toUpperCase(); // 大æåå°æåãç¡è¦
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
é ASCII æåã®ã½ã¼ã
é ASCII æåãã¤ã¾ãã¢ã¯ã»ã³ãè¨å·ä»ãæåï¼e, é, è, a, ä ãªã©ï¼ãå«ãæååãã½ã¼ãããå ´åãè±èªä»¥å¤ã®æåå㯠String.prototype.localeCompare() ã使ç¨ãã¦ãã ããããã®é¢æ°ã¯ããããã®æåãæ¯è¼ãã¦æ£ããé åºã§è¡¨ç¤ºãããã¨ãã§ãã¾ããï¼è¨³æ³¨: æ¥æ¬èªãã½ã¼ãããå ´åãå«ã¿ã¾ããï¼
const items = ["réservé", "premier", "communiqué", "café", "adieu", "éclair"];
items.sort((a, b) => a.localeCompare(b));
// items 㯠['adieu', 'café', 'communiqué', 'éclair', 'premier', 'réservé']
map ãå©ç¨ããã½ã¼ã
compareFn (æ¯è¼é¢æ°) ã¯ãé
åå
ã®è¦ç´ æ¯ã«è¤æ°åå¼ã³åºããããã¨ãããã¾ãããã compareFn ã®æ§è³ªã«ãã£ã¦ã¯ããããå¤å¤§ãªãªã¼ãã¼ããããããããå¯è½æ§ãããã¾ããcompareFn ãããããã®å¦çãè¡ãã°è¡ãã»ã©ãããã¦ã½ã¼ã対象ã®è¦ç´ æ°ãå¤ããã°å¤ãã»ã©ãã½ã¼ãã« map ãå©ç¨ããã¨å¹çãä¸ããã§ããããããªãã¡ã対象ã®é
åãä¸åº¦ã ãèµ°æ»ãã¦ã½ã¼ã対象ã®å®éã®å¤ãåãåºãã䏿çãªé
åã«æ ¼ç´ããä¸ã§ã½ã¼ããè¡ãããã®ä¸ã§ä¸æçãªé
åãèµ°æ»ãã¦æ£ãã並ã³é ãå®ç¾ããããããã§ãã
// ã½ã¼ãããé
å
const data = ["delta", "alpha", "charlie", "bravo"];
// ä½ç½®ã¨ã½ã¼ãå¤ãæã¤ãªãã¸ã§ã¯ããä¿æãã䏿çãªé
åã§ãã
const mapped = data.map((v, i) => ({ i, value: someSlowOperation(v) }));
// 忏ãããå¤ãå«ã対å¿ä»ããããé
åã®ã½ã¼ã
mapped.sort((a, b) => {
if (a.value > b.value) {
return 1;
}
if (a.value < b.value) {
return -1;
}
return 0;
});
const result = mapped.map((v) => data[v.i]);
ãã®ææ³ãå¿ç¨ãã mapsort ã¨ãããªã¼ãã³ã½ã¼ã¹ã®ã©ã¤ãã©ãªã¼ãå©ç¨ã§ãã¾ãã
sort() ã¯åãé åã¸ã®åç §ãè¿ã
sort() ã¡ã½ããã¯å
ã®é
åã¸ã®åç
§ãè¿ãã®ã§ãè¿ãããé
åã夿´ããã¨ãå
ã®é
åã夿´ããã¾ãã
const numbers = [3, 1, 4, 1, 5];
const sorted = numbers.sort((a, b) => a - b);
// numbers 㨠sorted ã¯ä¸¡æ¹ã¨ã [1, 1, 3, 4, 5]
sorted[0] = 10;
console.log(numbers[0]); // 10
å
ã®é
åã夿´ããã« sort() ãè¡ãããããä»ã®é
åã®ã¡ã½ããï¼map() ãªã©ï¼ã®ããã«ã·ã£ãã¼ã³ãã¼ãè¿ãããå ´åã¯ã toSorted() ã¡ã½ããã使ç¨ãã¦ãã ãããä»ã«ãã sort() ãå¼ã³åºãåã«ã¹ãã¬ããæ§æã¾ã㯠Array.from() ã使ç¨ãã¦ã·ã£ãã¼ã³ãã¼ãè¡ããã¨ãã§ãã¾ãã
const numbers = [3, 1, 4, 1, 5];
// [...numbers] creates a shallow copy, so sort() does not mutate the original
const sorted = [...numbers].sort((a, b) => a - b);
sorted[0] = 10;
console.log(numbers[0]); // 3
ã½ã¼ãã®å®å®æ§
ãã¼ã¸ã§ã³ 10 ï¼ã¾ã㯠ECMAScript 2019ï¼ä»¥éã仿§æ¸ã§ã¯ Array.prototype.sort ãå®å®ãã¦ãããã¨ã決ãããã¦ãã¾ãã
ä¾ãã°ãæç¸¾ã¨æ¨ªã«ä¸¦ãã çå¾ã®ãªã¹ãããã£ãã¨ãã¾ããçå¾ã®ãªã¹ãã¯ãã§ã«ã¢ã«ãã¡ãããé ã®ååã§ã½ã¼ãããã¦ãããã¨ã«æ³¨æãã¦ãã ããã
const students = [
{ name: "Alex", grade: 15 },
{ name: "Devlin", grade: 15 },
{ name: "Eagle", grade: 13 },
{ name: "Sam", grade: 14 },
];
ãã®é
åã grade ã§æé ã«ã½ã¼ãããå¾ã
students.sort((firstItem, secondItem) => firstItem.grade - secondItem.grade);
夿° students ã¯ä»¥ä¸ã®ãããªå¤ã«ãªãã¾ãã
[
{ name: "Eagle", grade: 13 },
{ name: "Sam", grade: 14 },
{ name: "Alex", grade: 15 }, // original maintained for similar grade (stable sorting)
{ name: "Devlin", grade: 15 }, // original maintained for similar grade (stable sorting)
];
éè¦ãªãã¨ã¯ãåãè©ç¹ãä¿æããå¦çï¼ä¾: Alex 㨠Devlinï¼ã¯ãã½ã¼ããå¼ã³åºãåã¨åãé çªã®ã¾ã¾ã§ãããã¨ã§ããããã¯ãå®å®ããã½ã¼ãã¢ã«ã´ãªãºã ãä¿è¨¼ãããã®ã§ãã
ãã¼ã¸ã§ã³ 10 ï¼ã¾ã㯠ECMAScript 2019ï¼ ä»¥åã¯ãã½ã¼ãã®å®å®æ§ãä¿è¨¼ããã¦ããªãããã以ä¸ã®ãããªçµæã«ãªãå¯è½æ§ãããã¾ãã
[
{ name: "Eagle", grade: 13 },
{ name: "Sam", grade: 14 },
{ name: "Devlin", grade: 15 }, // original order not maintained
{ name: "Alex", grade: 15 }, // original order not maintained
];
æ£ãããªãå½¢ã®æ¯è¼é¢æ°ã§ã®ã½ã¼ã
æ¯è¼é¢æ°ã解説ã§èª¬æããç¡å®³æ§ãå®å®æ§ãåå°æ§ãå対称æ§ãæ¨ç§»æ§ã®ã«ã¼ã«ããã¹ã¦æºããã¦ããªãå ´åãããã°ã©ã ã®åä½ã¯ãã¾ãå®ç¾©ããã¾ããã
ä¾ãã°ããã®ã³ã¼ããèãã¦ãã ããã
const arr = [3, 1, 4, 1, 5, 9];
const compareFn = (a, b) => (a > b ? 1 : 0);
arr.sort(compareFn);
ããã§ã® compareFn 颿°ã¯ãå対称æ§ãæºããã¦ããªããããæ£ããå½¢å¼ã§ã¯ããã¾ããã a > b ãªãã° 1 ãè¿ãã¾ããã a 㨠b ãå
¥ãæ¿ããã¨ãè² ã®å¤ã§ã¯ãªã 0 ãè¿ãããã«ãªãã¾ãããã®ãããçæãããé
åã¯ã¨ã³ã¸ã³ã«ãã£ã¦ç°ãªãã¾ããä¾ãã°ãV8ï¼ChromeãNode.js ãªã©ã§ä½¿ç¨ï¼ã JavaScriptCoreï¼Safari ã§ä½¿ç¨ï¼ã¯é
åãå
¨ãã½ã¼ãããã [3, 1, 4, 1, 5, 9] ãè¿ãã¾ãããSpiderMonkeyï¼Firefox ã§ä½¿ç¨ï¼ã¯ [1, 1, 3, 4, 5, 9] ã®ããã«æé ã«ä¸¦ã¹ãé
åãè¿ããã¨ã«ãªãã¾ãã
ããããcompareFn 颿°ãå°ã夿´ãã¦ã-1 ã 0 ãè¿ãããã«ããã¨ã次ã®ããã«ãªãã¾ãã
const arr = [3, 1, 4, 1, 5, 9];
const compareFn = (a, b) => (a > b ? -1 : 0);
arr.sort(compareFn);
ããã¨ã V8 ã JavaScriptCore ã§ã¯ [9, 5, 4, 3, 1, 1] ã®ããã«éé ã«ã½ã¼ãããã¾ããã SpiderMonkey ã§ã¯ [3, 1, 4, 1, 5, 9] ã®ããã«ãã®ã¾ã¾ã®å¤ãè¿ãã¾ãã
ãã®å®è£ ä¸ã®ä¸æ´åãããããã常㫠5 ã¤ã®å¶ç´ã«å¾ããã¨ã§ãæ¯è¼å¨ãæ£ããå½¢ã«ãããã¨ããå§ããã¾ãã
çé åã«ããã sort() ã®ä½¿ç¨
空ã®ã¹ãããã¯é åã®æ«å°¾ã«ç§»ããã¾ãã
console.log(["a", "c", , "b"].sort()); // ['a', 'b', 'c', empty]
console.log([, undefined, "a", "b"].sort()); // ["a", "b", undefined, empty]
é å以å¤ã®ãªãã¸ã§ã¯ãã«å¯¾ãã sort() ã®å¼ã³åºã
sort() ã¡ã½ãã㯠this ã® length ããããã£ãèªã¿åãã¾ããããã¦ã0 ãã length - 1 ã¾ã§ã®ç¯å²ã«ããæ¢åã®æ´æ°ãã¼ã®ããããã£ããã¹ã¦éåããã½ã¼ããã¦æ¸ãæ»ãã¾ããç¯å²å
ã«åå¨ããªãããããã£ãããå ´åã対å¿ããæ«å°¾ã®ããããã£ã¯åé¤ãããããããåå¨ããªãããããã£ãæ«å°¾ã«ã½ã¼ãããããã®ããã«ãªãã¾ãã
const arrayLike = {
length: 3,
unrelated: "foo",
0: 5,
2: 4,
};
console.log(Array.prototype.sort.call(arrayLike));
// { '0': 4, '1': 5, length: 3, unrelated: 'foo' }
仿§æ¸
| 仿§æ¸ |
|---|
| ECMAScript® 2027 Language Specification > # sec-array.prototype.sort > |
ãã©ã¦ã¶ã¼ã®äºææ§
é¢é£æ å ±
Array.prototype.sortã®å®å®æ§ãªã©ãå«ãã ç¾ä»£ã®å®è£ (core-js)- ã¤ã³ããã¯ã¹ä»ãã³ã¬ã¯ã·ã§ã³ã®ã¬ã¤ã
ArrayArray.prototype.reverse()Array.prototype.toSorted()String.prototype.localeCompare()TypedArray.prototype.sort()- Getting things sorted in V8 on v8.dev (2018)
- Stable
Array.prototype.sorton v8.dev (2019) Array.prototype.sortstability by Mathias Bynens