Ok işlevleri ve yıkıcı gibi ES2017 özelliklerini kullanan aynı şeyin biraz daha kısa versiyonu:
Fonksiyon
var stableSort = (arr, compare) => arr
.map((item, index) => ({item, index}))
.sort((a, b) => compare(a.item, b.item) || a.index - b.index)
.map(({item}) => item)
Giriş dizisini ve karşılaştırma işlevini kabul eder:
stableSort([5,6,3,2,1], (a, b) => a - b)
Ayrıca yerleşik Array.sort () işlevi gibi yerinde sıralama yapmak yerine yeni dizi döndürür .
Ölçek
Aşağıdaki input
diziyi alırsak , başlangıçta şu şekilde sıralanır weight
:
// sorted by weight
var input = [
{ height: 100, weight: 80 },
{ height: 90, weight: 90 },
{ height: 70, weight: 95 },
{ height: 100, weight: 100 },
{ height: 80, weight: 110 },
{ height: 110, weight: 115 },
{ height: 100, weight: 120 },
{ height: 70, weight: 125 },
{ height: 70, weight: 130 },
{ height: 100, weight: 135 },
{ height: 75, weight: 140 },
{ height: 70, weight: 140 }
]
Ardından şunu height
kullanarak sıralayın stableSort
:
stableSort(input, (a, b) => a.height - b.height)
Sonuçlar:
// Items with the same height are still sorted by weight
// which means they preserved their relative order.
var stable = [
{ height: 70, weight: 95 },
{ height: 70, weight: 125 },
{ height: 70, weight: 130 },
{ height: 70, weight: 140 },
{ height: 75, weight: 140 },
{ height: 80, weight: 110 },
{ height: 90, weight: 90 },
{ height: 100, weight: 80 },
{ height: 100, weight: 100 },
{ height: 100, weight: 120 },
{ height: 100, weight: 135 },
{ height: 110, weight: 115 }
]
Ancak aynı input
diziyi yerleşik kullanarak sıralamak Array.sort()
(Chrome / NodeJS'de):
input.sort((a, b) => a.height - b.height)
İadeler:
var unstable = [
{ height: 70, weight: 140 },
{ height: 70, weight: 95 },
{ height: 70, weight: 125 },
{ height: 70, weight: 130 },
{ height: 75, weight: 140 },
{ height: 80, weight: 110 },
{ height: 90, weight: 90 },
{ height: 100, weight: 100 },
{ height: 100, weight: 80 },
{ height: 100, weight: 135 },
{ height: 100, weight: 120 },
{ height: 110, weight: 115 }
]
Kaynaklar
Güncelleme
Array.prototype.sort
artık V8 v7.0 / Chrome 70'te kararlı!
Önceden, V8 10'dan fazla eleman içeren diziler için kararsız bir QuickSort kullanıyordu. Şimdi, kararlı TimSort algoritmasını kullanıyoruz.
kaynak