JavaScript μ sort ν¨μλ μμ μ λ ¬μΌκΉ?
π μμ μ λ ¬μ΄λ?
μμ μ λ ¬(stable sort)
μ λμΌν ν€ κ°μ λν΄ μ
λ ₯ μμλ₯Ό 보μ₯νλ μ λ ¬ μκ³ λ¦¬μ¦μ
λλ€.
κ·Έ λ°λμΈ λΆμμ μ λ ¬(unstable sort)
μ μ λ ¬ ν μ
λ ₯ μμλ₯Ό 보μ₯ν΄μ£Όμ§ μμ΅λλ€.
λνμ μΈ μμ μ λ ¬
μκ³ λ¦¬μ¦μ λ€μκ³Ό κ°μ΄ 3κ°μ§κ° μμ΅λλ€.
1οΈβ£ λ²λΈ μ λ ¬ (Bubble Sort)
2οΈβ£ μ½μ μ λ ¬ (Insertion Sort)
3οΈβ£ λ³ν© μ λ ¬ (Merge Sort)
κ·Έ μΈ ν΅ μ λ ¬
κ³Ό μ ν μ λ ¬
μ λΆμμ μ λ ¬
μ λνμ μΈ μκ³ λ¦¬μ¦μ
λλ€.
π JavaScript μ sort ν¨μ
JavaScript μ sort ν¨μλ μμ μ λ ¬μΌκΉ?
JavaScript
μ sort
ν¨μλ κ·Έλ λ€λ©΄ μμ μ λ ¬
μΌκΉμ?
Chrome 70 λ²μ μ΄μ μμλ μ¬μ€ JavaScript
μ ꡬν μ€νμ μμ μ λ ¬μ κ°μνμ§ μμλ€κ³ ν©λλ€.
λλ¬Έμ κ°κ°μ μμ§ κ΅¬ν체λ§λ€ μ λ ¬ λ°©μμ΄ λ€λ₯΄κ² λμ΄μμΌλ©° chrome
μ κ²½μ°μλ λ°°μ΄μ κΈΈμ΄μ λ°λΌ
μμ μ λ ¬μΌ μλ μκ³ λΆμμ μ λ ¬μΌ μλ μμλ€κ³ ν©λλ€.
νμ§λ§ chrome 70
μ΄ν λ²μ λΆν°λ Array.sort
λ₯Ό μμ μ λ ¬λ‘ κ΅¬ννλλ‘ μ€νμ΄ μ§μ λμκ³
κ·Έμ λ°λΌ λͺ¨λ λΈλΌμ°μ μμ μμ μ λ ¬μμ 보μ₯ν μ μκ² λμλ€κ³ ν©λλ€.
Chrome 70 μ΄μ μμ μ λ ¬ μκ³ λ¦¬μ¦
λ€μμ chrome 70
μ΄μ μ V8 μμ§ μ λ ¬ μκ³ λ¦¬μ¦ μμ€μ½λμ
λλ€.
// v8/array.js
/**
* β
Array.prototype.sort λ₯Ό μ μν©λλ€.
*/
DEFINE_METHOD(
GlobalArray.prototype,
sort(comparefn) {
if (!IS_UNDEFINED(comparefn) && !IS_CALLABLE(comparefn)) {
throw %make_type_error(kBadSortComparisonFunction, comparefn);
}
var array = TO_OBJECT(this);
var length = TO_LENGTH(array.length);
return InnerArraySort(array, length, comparefn);
}
);
/**
* β
μ€μ μ λ ¬μ μννλ ν¨μμ
λλ€.
*/
function InnerArraySort(array, length, comparefn) {
// In-place QuickSort algorithm.
// For short (length <= 10) arrays, insertion sort is used for efficiency.
if (!IS_CALLABLE(comparefn)) {
comparefn = /** κΈ°λ³Έ λΉκ΅ ν¨μ ν λΉ */
}
function InsertionSort(a, from, to) {/** */};
function QuickSort(a, from, to) {
// ...
while (true) {
// Insertion sort is faster for short arrays.
if (to - from <= 10) {
InsertionSort(a, from, to);
return;
}
// ...
};
if (length < 2) return array;
QuickSort(array, 0, num_non_undefined);
return array;
}
μ½λλ₯Ό 보면 Array.prototype.sort
λ μμ§ λ΄λΆμ μΌλ‘ InnerArraySort
ν¨μλ₯Ό νΈμΆνκ³
ν΄λΉ ν¨μ λ΄μμ λ°°μ΄μ κΈΈμ΄κ° 10
λ³΄λ€ μμ κ²½μ°μλ Insertion Sort
λ₯Ό μ¬μ©νκ³
κ·Έ μΈμλ Quick Sort
λ₯Ό μ¬μ©νλ κ²μ μ μ μμ΅λλ€.
μ΄νμ v8 μμ§μ Timsort
μκ³ λ¦¬μ¦μ μ¬μ©ν΄μ μ λ ¬ν©λλ€
stable
ν¨μ 보μ₯νκΈ° μν΄μ νμ¬ v8
μμ§μ TimSort
μκ³ λ¦¬μ¦μ μ΄μ©ν΄ μ λ ¬μ μνν©λλ€.
λ€μμ νμ¬ v8
μμ§ μμ€μ μ λ ¬ μκ³ λ¦¬μ¦ μ½λμ
λλ€.
ArrayTimSort
λ₯Ό νΈμΆν΄μ stable
ν μ λ ¬ κ²°κ³Όλ₯Ό λ°ννλ κ²μ νμΈν μ μμ΅λλ€.
// third_party/v8/builtins/array-sort.tq
ArrayPrototypeSort(
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
// ...
if (len < 2) return obj;
const sortState: SortState = NewSortState(obj, comparefn, len);
ArrayTimSort(context, sortState);
return obj;
}
π Chrome 70 μ΄μ μ μμ μ λ ¬μ ꡬννλ λ°©λ²
μμ μ λ ¬μ ꡬνλ κ°μ₯ μ¬μ΄ λ°©λ²μ κ° λ°°μ΄ μμμ key
κ°μ μ€λ¦μ°¨μμΌλ‘ μ§μ νλ κ²μ
λλ€.
μ΄λ κ² νλ©΄ λ λ°°μ΄ μμμ λΉκ΅ ν€κ°μ΄ λμΌν κ²½μ°μλ μΈλ±μ€λ‘ λΉκ΅νκΈ° λλ¬Έμ μμλ₯Ό 보μ₯ν μ μμ΅λλ€.
const stableSort = (arr, compare) =>
arr
.map((item, index) => ({ item, index }))
.sort((a, b) => compare(a.item, b.item) || a.index - b.index)
.map(({ item }) => item)
μ ν¨μλ₯Ό μ΄μ©ν΄μ μ λ ¬μ μννλ©΄ λ€μκ³Ό κ°μ κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€.
/** β
rating μ κΈ°μ€μΌλ‘ μ λ ¬μ μνν©λλ€. */
console.log(
stableSort(
[
{ name: "Abby", rating: 12 },
{ name: "Bandit", rating: 13 },
{ name: "Choco", rating: 14 },
{ name: "Daisy", rating: 12 },
{ name: "Elmo", rating: 12 },
{ name: "Falco", rating: 13 },
{ name: "Ghost", rating: 14 },
],
(a, b) => a.rating - b.rating
)
)[
/** κ·Έλ¬λ©΄ λ€μκ³Ό κ°μ μ λ ¬ κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€. */
({ name: "Abby", rating: 12 },
{ name: "Daisy", rating: 12 },
{ name: "Elmo", rating: 12 },
{ name: "Bandit", rating: 13 },
{ name: "Falco", rating: 13 },
{ name: "Choco", rating: 14 },
{ name: "Ghost", rating: 14 })
]
π μ°Έκ³ μλ£
'π¨βπ» web.dev > js.ts' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[JavaScript] Debounce μ Throttle μ λν΄ μμ보μ (0) | 2022.07.09 |
---|---|
[TypeScript] enum κ³Ό union type, μΈμ μ¨μΌν κΉ? (2) | 2022.07.09 |
[TypeScript] js.map νμΌμ 무μμΌκΉ? (0) | 2022.03.07 |
[JavaScript] Object.defineProperty μ λν΄μ (0) | 2022.03.06 |
[JavaScript] Promise.all vs Promise.allSettled (0) | 2022.02.20 |
π¬ λκΈ