Bir tamsayı dizisini doğru bir şekilde sıralama


847

Sadece tamsayılar içereceğini bildiğim bir diziden en yüksek ve en düşük değeri almaya çalışmak düşündüğümden daha zor görünüyor.

var numArray = [140000, 104, 99];
numArray = numArray.sort();
alert(numArray)

Bunu göstermesini beklerdim 99, 104, 140000. Bunun yerine gösterir 104, 140000, 99. Yani sıralama, değerleri dizeler olarak ele alıyor gibi görünüyor.

Tamsayı değeri üzerinde sıralamak için sıralama işlevini almanın bir yolu var mı?


10
Üst cevapların hiçbiri başa o Bildirimi tüm doğru kayan nokta değerlerinin; özellikle hiçbiri işlemez NaN. İlgilenen üst düzey bir cevap görmek güzel olurdu NaN.
Quuxplusone

3
BTW, çok ve çok sayıda tamsayı sıralıyorsanız, sayma sıralaması gibi bir tamsayı sıralama algoritması kullanmanın avantajları olacaktır . Ölçekleri dizinizin boyutuyla doğrusal olarak çalıştırmak için zaman sayma sıralaması O (n). Buradaki tüm çözümler daha az verimli olan karşılaştırma türünü kullanırken: O (n * log n).
Web_Designer

1
@Web_Designer Sayım sıralaması dizi ile değil sayı aralığına göre doğrusaldır. Örneğin, [1,1000000] sıralaması 2 adımdan fazla sürecektir, çünkü algoritma, hangi hücrenin değerinin 0'dan büyük olduğunu görmek için her dizi dizinini 1 ile 1000000 arasında taramak zorunda
kalacaktır.

2
@yters Bir hashmap kullanarak yalnızca sıralanan dizide görünen tamsayılara dikkat edebilirsiniz. Bu sıralama, dizi boyutu wrt doğrusal yapar.
Kevin

1
en hızlı yol, hem tarayıcıda hem de düğümde yerel olarak çalışan, her türlü girişi, hesaplanan alanları ve özel sıralama düzenlerini destekleyen izomorfik sıralama dizisi modülünü kullanmaktır .
Lloyd

Yanıtlar:


1235

Varsayılan olarak, sıralama yöntemi öğeleri alfabetik olarak sıralar. Sayısal olarak sıralamak için, yalnızca sayısal sıraları işleyen yeni bir yöntem ekleyin (sortNumber, aşağıda gösterilmiştir) -

var numArray = [140000, 104, 99];
numArray.sort(function(a, b) {
  return a - b;
});

console.log(numArray);

ES6'da bunu ok işlevleriyle basitleştirebilirsiniz:

numArray.sort((a, b) => a - b); // For ascending sort
numArray.sort((a, b) => b - a); // For descending sort

Belgeler:

Mozilla Array.prototype.sort() , Infinity veya NaN içermeyen diziler için bu karşılaştırma işlevini önerir. (Çünkü Inf - InfNaN değil, 0 değil).

Ayrıca nesneleri anahtar ile sıralama örnekleri.


148
Güzel. Ancak, javascript'ten sayısal bir tür elde etmenin gerçekten hazır bir yolu yok mu?
peirix

39
ahah bu kutunun dışında! Ancak gerçekten pratik değilseniz, javascriptinizin en başında işlevleri dizi sınıfı sınıfına bağlayabilirsiniz: // Array.prototype.sortNormal = function () {return this.sort (function (a, b) {return a - b})} // Şimdi herhangi bir dizide .sortNormal () öğesi sayısal olarak sıralanacaktır
Jack Franzen

13
Neden ab ve b> değil. Operasyon makinesi hatalarından kaçınmak için sonuncuyu öneriyorum
Luca Davanzo

35
@Velthune Karşılaştırma işlevi -1, 0 veya +1 döndürmelidir. a> b yalnızca doğru veya yanlış döndürür.
Iván Pérez

48
Bu kod bir Ok İşlevi kullanılarak kısaltılabilir . numberArray.sort((a, b) => (a - b));Yaşasın! Bence bu kullanıma hazır bir yola yakın. Not: JS motorunuzun Ok İşlevlerini destekleyip desteklemediğini kontrol edin.
Константин Ван

173

Sadece yukarıdaki cevapların tümüne dayanarak, aynı şekilde bir satırda da yapılabilirler:

var numArray = [140000, 104, 99];

// ES5
numArray = numArray.sort(function (a, b) {  return a - b;  });

// ES2015
numArray = numArray.sort((a, b) => a - b);

//outputs: 99, 104, 140000

8
Sabit @bodyflex: var arr = [140000, 104, 99].sort(function(a,b) { return a-b; });. Veya daha kompakt, ES6let arr = [140000, 104, 99].sort((a,b) => a-b);
00500005

1
Yukarıdaki bir yorumda söylediğim gibi, ok işlevleri burada kötü bir uyum ve kimsenin onları bu şekilde kullanmasını önermem. Kelimeleri kesip ok sözdizimi bir yan etkisi kullanıyor functionve return, ama aslında geçen ok işlevin gerçek amacını kullanmıyor this. Bu kod, bazı thisbağlamların geçmekte olduğunu gösterir, ancak yoktur. Sadece birkaç karakter kaydetmek için diğer geliştiriciler kodunuzu okumak için kafa karıştırıcı. Yan etkilere güvenmeyin - amaçlı kod!
bambery

12
@bambery Bağlam değişiklikleri için yalnızca bir ok işlevi kullanmanız gerektiğini düşünmüyorum…
Ted Morin

7
@bambery, aslında ok işlevinin ne yaptığını yanlış anlıyorsunuz. Bir şekilde thisişleve geçtiğini düşünüyorsunuz ama bu doğru değil. Aslında this, argumentsgenellikle üst değişkenlerin üzerine yazan bir ve değişkeni oluşturmayı ihmal eder . thisBir ok işlevi içinde kullanabilmenizin tek nedeni sözcüksel kapsam belirleme.
cuth

2
@bambery iyi yaşlanmadı ... üç yıl sonra ve modern javascript geliştirme neredeyse sadece ok işlevlerini kullanır. :)
Kip

71

array.sort varsayılan olarak sözlükbilimsel bir sıralama yapar, sayısal bir sıralama için kendi işlevinizi sağlar. İşte basit bir örnek:

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

numArray.sort(compareNumbers);

Ayrıca sıralamanın "yerinde" çalıştığını, ödeve gerek olmadığını unutmayın.


Yukarıdaki kodu anlamadım, nasıl "geri a - b" artan sıralama yapar?
vikramvi

bir <b ise, CompareNumbers negatif bir sayı döndürür. A> b ise pozitif olacaktır.
Paul Dixon

38

Bu cevap, mevcut cevapların bazılarına eşdeğerdir, ancak ECMAScript 6 ok işlevleri , okunabilirlikten ödün vermeden satır içi bir sıralama işlevi tanımlamamıza izin veren çok daha kompakt bir sözdizimi sağlar:

numArray = numArray.sort((a, b) => a - b);

Bugün çoğu tarayıcıda desteklenmektedir .


1
msgstr "okunabilirlikten ödün vermeden". Bu özneldir. Bazı basit tamsayılarla okunabilir. Karmaşık nesnelerle çalışırken ve bir özellik üzerinde sıralamak istiyorsunuz, çok fazla değil.
Tristan

3
@Tristan, bir nesnenin bir özelliği üzerinde sıralama bu sözdizimi kullanılarak hala oldukça temiz bir şekilde yapılabilir. Sıralamak istediğiniz nesnenin özelliği yapabileceğiniz bir sayı objArray=objArray.sort((a,b)=>a.numProperty - b.numProperty);ise ve özellik bir dize ise şunları yapabilirsiniz: objArray=objArray.sort((a,b)=>a.strProperty.localeCompare(b.strProperty))‌​;Söyledikten sonra, bu soru özellikle bir tamsayı dizisini sıralamayı ister
jjjjs

34

Herkes neden bir karşılaştırıcı funciton geçmesini önerdi şaşırdım sort(), bu sıralama gerçekten yavaş yapar!

Sayıları sıralamak için herhangi bir TypedArray oluşturun :

var numArray = new Uint32Array([140000, 104, 99]);
numArray = numArray.sort();
alert(numArray)


4
TypedArray kullanmak sıralamayı yaklaşık 5X hızlandırır. Daha da hızlı gitmek istiyorsanız hpc-algoritma npm paketi burada birkaç cevabın önerdiği Radix Sort and Counting Sort uygular.
DragonSpit

vay, bunun var olduğunu bilmiyordum!
pixelearth

21

Sıralama işlevinin bu kadar tuhaf davranmasının nedeni

Gönderen belgeler :

[...] dizi, her bir öğenin dize dönüştürmesine göre her karakterin Unicode kod noktası değerine göre sıralanır.

Dizinin unicode nokta değerlerini yazdırırsanız, o zaman temizlenir.

console.log("140000".charCodeAt(0));
console.log("104".charCodeAt(0));
console.log("99".charCodeAt(0));

//Note that we only look at the first index of the number "charCodeAt(  0  )"

Bu, "49, 49, 57" döndürür.

49 (unicode value of first number at 140000)
49 (unicode value of first number at 104)
57 (unicode value of first number at 99)

Şimdi, 140000 ve 104 aynı değerleri döndürdüğünden (49) ilk endeksi keser ve tekrar kontrol eder:

console.log("40000".charCodeAt(0));
console.log("04".charCodeAt(0));

//Note that we only look at the first index of the number "charCodeAt(  0  )"

52 (unicode value of first number at 40000)
40 (unicode value of first number at 04)

Bunu sıralarsak, o zaman alacağız:

40 (unicode value of first number at 04)
52 (unicode value of first number at 40000)

104, 140000'den önce gelir.

Sonuç olarak:

var numArray = [140000, 104, 99];
numArray = numArray.sort();
console.log(numArray)

104, 140000, 99

Sonuç:

sort() yalnızca sayıların ilk dizinine bakarak sıralama yapar. sort()bir sayının diğerinden daha büyük olup olmadığını umursamaz, basamakların unicode değerini karşılaştırır ve iki eşit unicode değeri varsa, bir sonraki basamak olup olmadığını kontrol eder ve karşılaştırır.

Doğru şekilde sıralamak için, buradasort() açıklandığı gibi bir karşılaştırma işlevini geçmeniz gerekir .


İpucu: Bu sadece benim açıklama, aslında kodu bakmadım. Bu cevaba tam olarak güvenme.
Siyah

17

Aks ile aynı fikirdeyim ama kullanmak yerine

return a - b;

Kullanmalısın

return a > b ? 1 : a < b ? -1 : 0;

18
Neden daha okunamayan üçlü operasyonunuzu kullanması gerektiğini açıklayabilir misiniz ? Anlayabildiğim kadarıyla aynı sonuca sahip olacağını.
stefannew

6
Bu cevap aynı zamanda eşit değerleri de dikkate alır ve aynı yerde bırakır.
Maarten00

23
Ve a - b değil mi?
Bryan Rayner

12
"return ab", bu sorunun özel durumu (javascript ve ints olduğu bilinen tüm giriş öğeleri) için yeterli olabilir, ancak şahsen üçlü formu tercih ederim çünkü daha kanoniktir - daha fazla durumda, daha fazla programlama dilinde çalışır , daha fazla veri türüyle. Örneğin, C'de ab taşabilir, sonsuz döngüye, hafızayı bozmaya, çökmeye vb. Yol açar. Yani, NaN'ler veya karışık türler varsa üçlü form bile düzgün çalışmayacaktır.
Don Hatch

8
>Ve <yine dizeleri olarak a ve b karşılaştırın.
vriesdemichael

11

Yeni ES6 dünyasında bir çeşit yapmak çok daha kolay

numArray.sort((a,b) => a-b);

Tek ihtiyacın olan bu :)


10

JavaScript'te sort () yönteminin varsayılan davranışı, bir dizideki değerleri alfabetik olarak sıralamaktır.

Sayıya göre sıralamak için sayısal bir sıralama işlevi tanımlamanız gerekir (ki bu çok kolaydır):

...
function sortNumber(a, b)
{
  return a - b;
}

numArray = numArray.sort(sortNumber);

8

Array.prototype.sort (), dizileri sıralamak için kullanılan yöntemdir, ancak bilmemiz gereken birkaç sorun vardır.

Sıralama düzeni varsayılan olarak sözlükçedir ve dizideki değer türlerine bakılmaksızın sayısal değildir. Dizi tüm sayılar olsa bile, tüm değerler dizeye dönüştürülecek ve sözlükbilimsel olarak sıralanacaktır.

Yani sort () ve reverse () yöntemini aşağıdaki gibi özelleştirmemiz gerekir.

Önerilen URL

Dizi içindeki sayıları sıralamak için

numArray.sort(function(a, b)
{
    return a - b;
});

Dizi içindeki sayıları ters çevirmek için

numArray.sort(function(a, b)
{
    return b - a;
});

Önerilen URL


6

Soru zaten cevaplandı, en kısa yol sort()yöntemi kullanmaktır . Ancak sayı dizinizi sıralamanın daha fazla yolunu arıyorsanız ve ayrıca döngüleri de seviyorsanız, aşağıdakileri kontrol edin

Ekleme sıralaması

artan:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
    var target = numArray[i];
    for (var j = i - 1; j >= 0 && (numArray[j] > target); j--) {
        numArray[j+1] = numArray[j];
    }
    numArray[j+1] = target
}
console.log(numArray);

Azalan:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
    var target = numArray[i];
    for (var j = i - 1; j >= 0 && (numArray[j] < target); j--) {
        numArray[j+1] = numArray[j];
    }
    numArray[j+1] = target
}
console.log(numArray);

Seçim sıralaması:

artan:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
    var min = i;
    for (var j = i + 1; j < numArray.length; j++) {
        if (numArray[j] < numArray[min]) {
            min = j;
        }
    }
    if (min != i) {
        var target = numArray[i];
        numArray[i] = numArray[min];
        numArray[min] = target;
    }
}
console.log(numArray);

Azalan:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
    var min = i;
    for (var j = i + 1; j < numArray.length; j++) {
        if (numArray[j] > numArray[min]) {
            min = j;
        }
    }
    if (min != i) {
        var target = numArray[i];
        numArray[i] = numArray[min];
        numArray[min] = target;
    }
}
console.log(numArray);

İyi eğlenceler


Bunlardan herhangi Are aslında kullanmaktan daha küçük diziler için hızlı sort()gibi bir TypedArray üzerine bu cevabı da anlaşılacağı . Tabii ki bunlar O (n ^ 2) algoritmaları olduğu için orta ve büyük diziler için daha hızlı olmayacaklardır.
Peter Cordes

5

Aşağıdaki 'sayısal' işlevi, bir geri arama işlevi sağlandığında birçok durumda sayı dizisini sayısal olarak sıralama amacına hizmet eder:

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

array.sort(numerically); 

Ancak, dizinin çok büyük ve negatif sayılar içerdiği bazı nadir durumlarda, ab'nin sonucu, JavaScript'in baş edebileceği en küçük sayıdan daha küçük hale gelmesi nedeniyle bir taşma hatası oluşabilir.

Sayısal olarak yazmanın daha iyi bir yolu şöyledir:

function numerically(a, b){
   if(a < b){
      return -1;
   } else if(a > b){
      return 1;
   } else {
      return 0;
   }
}

1
JavaScript numaraları kayan noktalı. IEEE754, + -Infinity'ye aşırı akış ve altnormal veya + -0.0'a düşük de dahil olmak üzere taşma ve taşma kurallarını tanımlar. İki sayının çıkarılmasının, hem büyük hem de yakın eşit olsalar bile + -0.0'a düşebileceğini düşünmüyorum. İki çift arasındaki fark her zaman sıfır olmayan bir çift olarak temsil edilebilir (taşmadığı sürece DBL_MIN - DBL_MAX), ancak taşma mümkün değildir. Felaket iptali sonucu a-bkesinleştirerek
Peter Cordes

4

tanımsız, null ve NaN ile başa çıkmak için: Null 0, NaN gibi davranır ve undefined sona erer.

array = [3, 5, -1, 1, NaN, 6, undefined, 2, null]
array.sort((a,b) => isNaN(a) || a-b)
// [-1, null, 1, 2, 3, 5, 6, NaN, undefined]

3

Yalnızca normal öğe değerleri dizisi için:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
**output : [1, 2, 2, 24, 64, 545, 676]**

var array2 = ["v","a",545,676,64,2,"24"]
**output: ["a", "v", 2, "24", 64, 545, 676]**

Bir nesne dizisi için:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

**output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]**

2

Güncelleme! smartSortDaha da eğlenceli hale getiren prop katkısı için cevabın en altına gidin ! Her şeyin
dizilerini sıralar !

Bu işlevin kişisel favori formum Artan veya Azalan için bir paramite izin veriyor:

function intArraySort(c, a) {
    function d(a, b) { return b - a; }
    "string" == typeof a && a.toLowerCase();
    switch (a) {
        default: return c.sort(function(a, b) { return a - b; });
        case 1:
                case "d":
                case "dc":
                case "desc":
                return c.sort(d)
    }
};

Kullanımı kadar basit:

var ara = function getArray() {
        var a = Math.floor(Math.random()*50)+1, b = [];
        for (i=0;i<=a;i++) b.push(Math.floor(Math.random()*50)+1);
        return b;
    }();

//    Ascending
intArraySort(ara);
console.log(ara);

//    Descending
intArraySort(ara, 1);
console.log(ara);

//    Ascending
intArraySort(ara, 'a');
console.log(ara);

//    Descending
intArraySort(ara, 'dc');
console.log(ara);

//    Ascending
intArraySort(ara, 'asc');
console.log(ara);

jsFiddle


Veya Kod Parçacığı Örneği Burada!

function intArraySort(c, a) {
	function d(a, b) { return b - a }
	"string" == typeof a && a.toLowerCase();
	switch (a) {
		default: return c.sort(function(a, b) { return a - b });
		case 1:
		case "d":
		case "dc":
		case "desc":
		return c.sort(d)
	}
};

function tableExample() {
	var d = function() {
			var a = Math.floor(50 * Math.random()) + 1,
				b = [];
			for (i = 0; i <= a; i++) b.push(Math.floor(50 * Math.random()) + 1);
			return b
		},
		a = function(a) {
			var b = $("<tr/>"),
				c = $("<th/>").prependTo(b);
			$("<td/>", {
				text: intArraySort(d(), a).join(", ")
			}).appendTo(b);
			switch (a) {
				case 1:
				case "d":
				case "dc":
				case "desc":
					c.addClass("desc").text("Descending");
					break;
				default:
					c.addClass("asc").text("Ascending")
			}
			return b
		};
	return $("tbody").empty().append(a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1))
};

tableExample();
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: .25em .5em; vertical-align: top; }
.asc { color: red; }
.desc { color: blue }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table><tbody></tbody></table>


.smartSort ('asc' | 'desc')

Şimdi birden fazla öğe ile dolu bir diziyi sıralayan bir sıralama yöntemi ile daha da eğlenin! Şu anda "ilişkilendirici" (aka, dize anahtarları) kapsamaz, ancak her tür değeri kapsar! Sadece birden çok değer sıralanır ascveyadesc buna göre , aynı zamanda değerlerin "gruplarının" sabit "konumunu" da koruyacaktır. Başka bir deyişle; ints her zaman ilk önce, sonra dizeleri gel, sonra diziler (evet, bu çok boyutlu yapıyorum!), sonra Nesneler (filtrelenmemiş, eleman, tarih) ve nihayet tanımsız ve boş!

"Neden?" sen sor. Neden olmasın!

Şimdi 2 çeşit geliyor! Birincisi Object.defineProperty, yöntemi Array.protoypeObject'e eklemek için kullandığı için daha yeni tarayıcılar gerektirir . Bu kolaylığı sağlar doğal gibi kullanım: myArray.smartSort('a'). Daha eski tarayıcılar için uygulamanız gerekiyorsa veya yalnızca yerel Nesneleri değiştirmek istemiyorsanız, Yalnızca Yöntem sürümüne gidin.

/* begin */
/* KEY NOTE! Requires EcmaScript 5.1 (not compatible with older browsers) */
;;(function(){if(Object.defineProperty&&!Array.prototype.smartSort){var h=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a>b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("a");b instanceof Array&&b.smartSort("a");if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("a"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("a"),a.id==e[0]?1:-1;e=[a.tagName, b.tagName].smartSort("a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("a"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d"); return a[d].tagName==c[0]?1:-1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]>g[1]},k=function(a,b){if(null== a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("d");b instanceof Array&&b.smartSort("d");if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("d"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("d"),a.id==e[0]?-1:1;e=[a.tagName,b.tagName].smartSort("d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("d"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1;if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]};Object.defineProperty(Array.prototype,"smartSort",{value:function(){return arguments&& (!arguments.length||1==arguments.length&&/^a([sc]{2})?$|^d([esc]{3})?$/i.test(arguments[0]))?this.sort(!arguments.length||/^a([sc]{2})?$/i.test(arguments[0])?h:k):this.sort()}})}})();
/* end */

jsFiddle Array.prototype.smartSort ('asc | desc')


Kullanımı basit! İlk önce çılgın bir dizi yapın:

window.z = [ 'one', undefined, $('<span />'), 'two', null, 2, $('<div />', { id: 'Thing' }), $('<div />'), 4, $('<header />') ];
z.push(new Date('1/01/2011'));
z.push('three');
z.push(undefined);
z.push([ 'one', 'three', 'four' ]);
z.push([ 'one', 'three', 'five' ]);
z.push({ a: 'a', b: 'b' });
z.push({ name: 'bob', value: 'bill' });
z.push(new Date());
z.push({ john: 'jill', jack: 'june' });
z.push([ 'abc', 'def', [ 'abc', 'def', 'cba' ], [ 'cba', 'def', 'bca' ], 'cba' ]);
z.push([ 'cba', 'def', 'bca' ]);
z.push({ a: 'a', b: 'b', c: 'c' });
z.push({ a: 'a', b: 'b', c: 'd' });

Sonra sıralayın!

z.smartSort('asc'); // Ascending
z.smartSort('desc'); // Descending

Yalnızca Yöntem

Öncekiyle aynı, sadece basit bir yöntem hariç!

/* begin */
/* KEY NOTE! Method `smartSort` is appended to native `window` for global use. If you'd prefer a more local scope, simple change `window.smartSort` to `var smartSort` and place inside your class/method */
window.smartSort=function(){if(arguments){var a,b,c;for(c in arguments)arguments[c]instanceof Array&&(a=arguments[c],void 0==b&&(b="a")),"string"==typeof arguments[c]&&(b=/^a([sc]{2})?$/i.test(arguments[c])?"a":"d");if(a instanceof Array)return a.sort("a"==b?smartSort.asc:smartSort.desc)}return this.sort()};smartSort.asc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a> b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.asc);b instanceof Array&&b.sort(smartSort.asc);if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c], b[c]],"a"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"a"),a.id==e[0]?1:-1;e=smartSort([a.tagName,b.tagName],"a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g), "a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"a"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"a");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1; if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==c[0]?1:-1}g=[a,b].sort();return g[0]>g[1]};smartSort.desc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)? 1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.desc);b instanceof Array&&b.sort(smartSort.desc);if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c],b[c]],"d"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]], b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"d"),a.id==e[0]?-1:1;e=smartSort([a.tagName,b.tagName],"d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g),"a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&& b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"d"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1; if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]}
/* end */

kullanın:

z = smartSort(z, 'asc'); // Ascending
z = smartSort(z, 'desc'); // Descending

jsFiddle Method smartSort (Dizi, "asc | desc")


2

Bu kodu deneyin:

HTML:

<div id="demo"></div>

JavaScript kodu:

<script>
    (function(){
        var points = [40, 100, 1, 5, 25, 10];
        document.getElementById("demo").innerHTML = points;
        points.sort(function(a, b){return a-b});
        document.getElementById("demo").innerHTML = points;
    })();
</script>

2

Bu kodu aşağıdaki gibi deneyin

var a = [5, 17, 29, 48, 64, 21];
function sortA(arr) {
return arr.sort(function(a, b) {
return a - b;
})
;} 
alert(sortA(a));

doğru değil mi?
user7125929

1
var numArray = [140000, 104, 99];
numArray = numArray.sort((a,b) => a-b);
alert(numArray)

4
StackOverflow'a hoş geldiniz. Cevabınız kabul edilen cevapla aynı. Cevabınızın kabul edilen cevap yerine neden tercih edilmesi gerektiğini söylemek için herhangi bir açıklama ekleyebilir misiniz?
Sadece Ged

1

JavaScript'te gerekli olmasa da, -1, 0 veya 1'i kesinlikle döndürmek istiyorsanız ( uzay gemisi operatörünün PHP'de nasıl çalıştığına benzer ), kullanabilirsiniz .sort() compareFunctionMath.sign()

compareFunctionAşağıda kesin olarak döner -1, 0 ya da 1:

numArray.sort((a, b) => Math.sign(a - b));

Not: Math.sign() Internet Explorer'da desteklenmez.


0

Bu, Array prototipinde bir yöntem olarak zaten önerilen ve kabul edilen çözümdür:

Array.prototype.sortNumeric = function () {
    return this.sort((a, b) => a - b);
};
Array.prototype.sortNumericDesc = function () {
    return this.sort((a, b) => b - a);
};

0

Sıralama yöntemi Dizi öğelerini dizeye dönüştürür. Bu nedenle, aşağıdaki şekilde dizi öğelerine sahip ondalık sayılarla da iyi çalışır.

let productPrices = [10.33, 2.55, 1.06, 5.77];
console.log(productPrices.sort((a,b)=>a-b));

Ve size beklenen sonucu verir.


0

Sıralama yöntemini geçersiz kılma.

Array.prototype.sortInt = function(){
    this.sort(function(a,b){return a-b});
}


numbers = [12,8,21,5,1,34];
numbers.sortInt()
//output -> [1,5,8,12,21,34]

0

Varsayılan sıralama işlevi sözlük sırasıyla sıralanır:

var ar = [10000,3,200];
console.log(ar.sort());
//it will sort like :=> [10000, 200, 3]

Yukarıdaki rakamlar için istediğimiz durum değildir. Dolayısıyla, tamsayılarınız varsa ve varsayılan sıralama işlevi çalışmıyorsa (sözlük sırasına göre sıralandığı için) kendi işlevinizi uygulamanız gerekir:

var ar = [10000,3,-09,200];
function customSortHelpForNumber(number1, number2){
     return number1-number2;
}
console.log(ar.sort(customSortHelpForNumber));
//it will sort like :=> [3, 200, 10000]

Umarım nasıl çalıştığını aklınızda bulundurursunuz? Burada sıralama işlevinde bir yöntem sağladığımızda, her seferinde iki sayı geçer ve sayı geri dönerse

  • -ve değer veya 0, ilk sayıyı yerinde tutar
  • + ve değer alışverişi yeri.

Bunu tüm sayılar için takip ederek tamsayı dizisini sıralar.

ES6 kullanıyorsanız bir ok işlevi yazın:

console.log(ar.sort((num1,num2)=> num1-num2));
    //it will sort like :=> [3, 200, 10000]

-1

İşte utils kütüphanesinde benim dizi dizi fonksiyonu:

sortArray: function(array) {
    array.sort(function(a, b) {
        return a > b;
    });
},

# Let's test a string array
var arr = ['bbc', 'chrome', 'aux', 'ext', 'dog'];
utils.sortArray(arr);
console.log(arr);
>>> ["aux", "bbc", "chrome", "dog", "ext", remove: function]

# Let's test a number array
var arr = [55, 22, 1425, 12, 78];
utils.sortArray(arr);
console.log(arr);
>>> [12, 22, 55, 78, 1425, remove: function]

3
Bu çok yanlış! sıralama işlevi, doğru veya yanlış değil, negatif, 0 veya pozitif sayılar döndürmelidir.
jperelli

@Jperelli'nin belirttiği gibi, sıralama işlevinin döndürülmesi için bir boole değil bir sayıya ihtiyacı vardır (ve eşit, yukarıda ve aşağıda 3 olası durumun olduğu göz önüne alındığında, bu istikrarlı bir sıralama için gereklidir). Cevabınızın belirtildiği gibi, işe yaramıyor. a-byerine kullanılmalıdır. (Fantezi olabilir ve yapabilirsiniz Number(a>b)-0.5, ancak bu hala istikrarlı bir tür değildir).
ecc521
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.