Cara mengurutkan array bilangan bulat dengan benar

849

Mencoba untuk mendapatkan nilai tertinggi dan terendah dari array yang saya tahu hanya akan berisi bilangan bulat tampaknya lebih sulit daripada yang saya kira.

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

Saya berharap ini untuk ditampilkan 99, 104, 140000. Sebaliknya itu menunjukkan 104, 140000, 99. Jadi sepertinya jenis ini menangani nilai sebagai string.

Apakah ada cara untuk mendapatkan fungsi sortir untuk benar-benar mengurutkan nilai integer?

peirix
sumber
10
Perhatikan bahwa tidak ada jawaban teratas yang menangani semua nilai floating-point dengan benar; khususnya, tidak ada yang menangani NaN. Akan menyenangkan untuk melihat jawaban berperingkat tinggi yang berhubungan dengan NaN.
Quuxplusone
3
BTW, jika Anda menyortir banyak dan banyak bilangan bulat itu akan menjadi keuntungan untuk menggunakan algoritma semacam bilangan bulat seperti menghitung jenis . Jenis penghitungan waktu akan diperlukan untuk menjalankan skala secara linear dengan ukuran array Anda: O (n). Sedangkan semua solusi di sini menggunakan jenis perbandingan yang kurang efisien: O (n * log n).
Web_Designer
1
@Web_Designer Jenis penghitungan adalah linier mengenai rentang angka, bukan array. Misalnya, pengurutan [1.100.000] akan membutuhkan lebih dari 2 langkah, karena algoritme harus memindai setiap indeks array antara 1 hingga 10.000 untuk melihat nilai sel mana yang lebih besar dari 0.
ya
2
@yters Menggunakan hashmap, Anda hanya bisa memperhatikan bilangan bulat yang muncul dalam array yang sedang diurutkan. Ini membuat semacam linear wrt ukuran array.
Kevin
1
cara tercepat adalah dengan menggunakan modul array- isomorfik yang bekerja secara native di kedua browser dan node, mendukung semua jenis input, bidang yang dikomputasi dan pesanan penyortiran khusus.
Lloyd

Jawaban:

1236

Secara default, metode sortir mengurutkan elemen berdasarkan abjad. Untuk mengurutkan secara numerik cukup tambahkan metode baru yang menangani jenis angka (sortNumber, ditunjukkan di bawah) -

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

console.log(numArray);

Di ES6, Anda dapat menyederhanakan ini dengan fungsi panah:

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

Dokumentasi:

Mozilla Array.prototype.sort()merekomendasikan fungsi perbandingan ini untuk array yang tidak mengandung Infinity atau NaN. (Karena Inf - InfNaN, bukan 0).

Juga contoh menyortir objek dengan kunci.

aks
sumber
149
Bagus. Tetapi apakah benar-benar tidak ada cara di luar kotak untuk mendapatkan semacam angka dari javascript?
peirix
39
ahah ini di luar kotak! Tetapi jika Anda benar-benar tidak praktis Anda dapat mengikat fungsi ke kelas kelas array di awal javascript Anda: // Array.prototype.sortNormal = function () {return this.sort (function (a, b) {mengembalikan a - b})} // Sekarang memanggil .sortNormal () pada array apa pun akan mengurutkannya secara numerik
Jack Franzen
13
Kenapa ab dan bukan a> b. Saya menyarankan yang terakhir untuk menghindari kesalahan mesin operasi
Luca Davanzo
35
@Velthune Fungsi membandingkan harus mengembalikan -1, 0 atau +1. a> b hanya akan mengembalikan benar atau salah.
Iván Pérez
48
Kode ini dapat disingkat menggunakan Fungsi Panah . numberArray.sort((a, b) => (a - b));Yay! Saya pikir ini dekat dengan cara out-of-the-box. Catatan: periksa apakah mesin JS Anda mendukung Fungsi Panah.
Константин Ван
174

Hanya dengan membangun semua jawaban di atas, mereka juga dapat dilakukan dalam satu baris seperti ini:

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
MarzSocks
sumber
8
@bodyflex Tetap: var arr = [140000, 104, 99].sort(function(a,b) { return a-b; });. Atau lebih ringkas, di ES6let arr = [140000, 104, 99].sort((a,b) => a-b);
00500005
1
Seperti yang saya katakan di komentar di atas, fungsi panah tidak cocok di sini dan saya akan mencegah siapa pun untuk menggunakannya dengan cara ini. Anda menggunakan efek samping dari sintaks panah untuk memotong kata-kata functiondan return, tetapi sebenarnya tidak menggunakan tujuan sebenarnya dari fungsi panah untuk meneruskan this. Kode ini menyiratkan ada beberapa thiskonteks yang lewat terjadi, tetapi tidak ada. Membingungkan bagi pengembang lain untuk membaca kode Anda, hanya untuk menyimpan beberapa karakter. Jangan bergantung pada efek samping - kode dengan tujuan!
bambery
12
@berambery Saya tidak berpikir bahwa Anda perlu menggunakan fungsi panah secara eksklusif untuk perubahan konteks ...
Ted Morin
7
@berbery, Anda benar-benar salah memahami apa yang dilakukan fungsi panah. Anda berpikir bahwa itu entah bagaimana masuk thiske dalam fungsi tetapi itu tidak benar. Ini sebenarnya lalai untuk membuat thisdan argumentsvariabel yang biasanya menimpa variabel induk. Satu-satunya alasan Anda dapat menggunakan thisdi dalam fungsi panah adalah pelingkupan leksikal.
cuth
2
@berambery yang tidak menua dengan baik ... tiga tahun kemudian dan pengembangan javascript modern menggunakan fungsi panah hampir secara eksklusif. :)
Kip
71

array.sort melakukan pengurutan leksikografis secara default, untuk pengurutan numerik, berikan fungsi Anda sendiri. Berikut ini contoh sederhana:

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

numArray.sort(compareNumbers);

Perhatikan juga bahwa sorting berfungsi "di tempat", tidak perlu untuk penugasan.

Paul Dixon
sumber
Saya tidak mengerti kode di atas, bagaimana "mengembalikan a - b" penyortiran naik?
vikramvi
jika a <b, compareNumbers mengembalikan angka negatif. Jika a> b, itu akan positif. Jika sama, ia mengembalikan 0.
Paul Dixon
38

Jawaban ini setara dengan beberapa jawaban yang ada, tetapi fungsi panah ECMAScript 6 memberikan sintaks yang jauh lebih kompak yang memungkinkan kami untuk mendefinisikan fungsi inline sort tanpa mengorbankan keterbacaan:

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

Ini didukung di sebagian besar browser saat ini .

jjjs
sumber
1
"Tanpa mengorbankan keterbacaan". Ini subjektif. Dengan beberapa bilangan bulat sederhana itu dapat dibaca. Ketika bekerja dengan objek yang lebih kompleks dan Anda ingin mengurutkan pada properti, jangan terlalu banyak.
Tristan
3
@ Christian, mengurutkan pada properti objek masih dapat dilakukan dengan cukup bersih menggunakan sintaks ini. Jika properti objek yang ingin Anda urutkan adalah angka yang dapat Anda lakukan: objArray=objArray.sort((a,b)=>a.numProperty - b.numProperty);dan jika properti adalah string yang dapat Anda lakukan: objArray=objArray.sort((a,b)=>a.strProperty.localeCompare(b.strProperty))‌​;Yang telah dikatakan, pertanyaan ini secara spesifik menanyakan tentang pengurutan array bilangan bulat
jjjjs
34

Saya terkejut mengapa semua orang merekomendasikan untuk melewatkan fungsi pembanding sort(), yang membuat penyortiran menjadi sangat lambat!

Untuk mengurutkan angka, cukup buat TypedArray apa saja :

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

dy_
sumber
4
Menggunakan TypedArray mempercepat pengurutan sekitar 5X. Jika Anda ingin lebih cepat lagi, hpc-algoritme, paket npm, menerapkan Radix Sort dan Counting Sort yang disarankan beberapa jawaban di sini.
DragonSpit
wow, tidak tahu ini ada!
pixelearth
21

Alasan mengapa fungsi sort berperilaku sangat aneh

Dari dokumentasi :

[...] array diurutkan berdasarkan nilai titik kode Unicode setiap karakter, sesuai dengan konversi string setiap elemen.

Jika Anda mencetak nilai unicode point dari array maka itu akan menjadi jelas.

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  )"

Ini mengembalikan: "49, 49, 57".

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

Sekarang, karena 140000 dan 104 mengembalikan nilai yang sama (49) itu memotong indeks pertama dan memeriksa lagi:

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)

Jika kita menyortir ini, maka kita akan mendapatkan:

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

jadi 104 datang sebelum 140000.

Jadi hasil akhirnya adalah:

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

104, 140000, 99

Kesimpulan:

sort()tidak menyortir dengan hanya melihat indeks angka pertama. sort()tidak peduli jika bilangan bulat lebih besar dari yang lain, ia membandingkan nilai unicode dari digit, dan jika ada dua nilai unicode yang sama, maka ia memeriksa apakah ada digit berikutnya dan membandingkannya juga.

Untuk mengurutkan dengan benar, Anda harus melewati fungsi bandingkan agar sort()seperti dijelaskan di sini .

Hitam
sumber
Petunjuk: Ini hanya penjelasan saya, saya tidak benar-benar mencari kode. Jadi jangan sepenuhnya percaya pada jawaban ini.
Hitam
17

Saya setuju dengan aks, namun alih-alih menggunakan

return a - b;

Kamu harus menggunakan

return a > b ? 1 : a < b ? -1 : 0;
pengguna3587638
sumber
18
Bisakah Anda menjelaskan mengapa orang harus menggunakan operasi ternary Anda yang lebih tidak dapat dibaca? Sejauh yang saya tahu itu akan memiliki hasil yang sama.
stefannew
6
Jawaban ini juga mempertimbangkan nilai yang sama dan membiarkannya di tempat yang sama.
Maarten00
23
Dan a-b tidak?
Bryan Rayner
12
"return ab" mungkin cukup untuk kasus tertentu dari pertanyaan ini (javascript, dan semua item input dikenal sebagai int), tetapi secara pribadi saya lebih suka bentuk ternary karena lebih kanonik - ini berfungsi dalam lebih banyak kasus, dalam lebih banyak bahasa pemrograman , dengan lebih banyak tipe data. Misalnya dalam C, ab dapat meluap, mengarah ke semacam perulangan tak berujung, merusak memori, menabrak, dll. Yang mengatakan, bahkan bentuk ternary tidak akan berfungsi dengan baik jika ada NaNs atau tipe campuran yang terlibat.
Don Hatch
8
The >dan <masih membandingkan a dan b sebagai string.
vriesdemichael
11

Di dunia ES6 baru itu jauh lebih mudah dilakukan sejenis

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

Itulah yang Anda butuhkan :)

Chait
sumber
10

Dalam JavaScript, perilaku default metode sort () adalah untuk mengurutkan nilai-nilai dalam array secara abjad.

Untuk mengurutkan berdasarkan angka Anda harus mendefinisikan fungsi pengurutan angka (yang sangat mudah):

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

numArray = numArray.sort(sortNumber);
Peter Mortensen
sumber
8

Array.prototype.sort () adalah metode buka untuk menyortir array, tetapi ada beberapa masalah yang perlu kita waspadai.

Urutan penyortiran adalah secara default leksikografis dan bukan numerik terlepas dari jenis nilai dalam array. Bahkan jika array adalah semua angka, semua nilai akan dikonversi ke string dan diurutkan secara leksikografis.

Jadi sebaiknya kita perlu menyesuaikan metode sort () dan reverse () seperti di bawah ini.

URL yang dirujuk

Untuk menyortir angka di dalam array

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

Untuk membalikkan angka di dalam array

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

URL yang dirujuk

Merbin Joe
sumber
6

Pertanyaannya sudah dijawab, cara terpendek adalah menggunakan sort()metode. Tetapi jika Anda mencari lebih banyak cara untuk mengurutkan susunan angka, dan Anda juga menyukai siklus, periksa yang berikut ini

Jenis penyisipan

Naik:

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);

Menurun:

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);

Sortir seleksi:

Naik:

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);

Menurun:

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);

Selamat bersenang-senang

Bunuh Diri Komersial
sumber
Apakah ini sebenarnya lebih cepat untuk array kecil daripada menggunakan sort()pada TypedArray seperti jawaban ini sarankan . Tentu saja mereka tidak akan lebih cepat untuk array sedang hingga besar karena ini adalah algoritma O (n ^ 2).
Peter Cordes
5

Fungsi 'numerik' di bawah ini berfungsi untuk menyortir array angka secara numerik dalam banyak kasus ketika disediakan sebagai fungsi panggilan balik:

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

array.sort(numerically); 

Namun dalam beberapa kasus yang jarang terjadi, di mana array berisi angka yang sangat besar dan negatif, kesalahan overflow dapat terjadi karena ab menjadi lebih kecil daripada angka terkecil yang bisa diatasi oleh JavaScript.

Jadi cara yang lebih baik untuk menulis fungsi numerik adalah sebagai berikut:

function numerically(a, b){
   if(a < b){
      return -1;
   } else if(a > b){
      return 1;
   } else {
      return 0;
   }
}
leet101
sumber
1
Nomor JavaScript adalah titik apung. IEEE754 mendefinisikan aturan overflow dan underflow, termasuk overflow ke + -Infinity, dan underflow ke subnormal atau + -0.0. Saya tidak berpikir pengurangan dua angka dapat underflow ke + -0.0 bahkan jika keduanya besar dan dekat sama. Perbedaan antara dua ganda selalu dianggap sebagai non-nol ganda (kecuali meluap, seperti DBL_MIN - DBL_MAX) tetapi underflow tidak mungkin. Pembatalan katastropik membuat hasilnya tidak tepat, kehilangan sebagian besar "digit signifikan" -nya, tetapi a-bakan selalu menjadi nol dan memiliki tanda yang tepat untuk a! = B.
Peter Cordes
4

untuk menangani undefined, null, dan NaN: Null berperilaku seperti 0, NaN dan undefined berakhir.

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]
Ali Khosro
sumber
3

Hanya untuk array normal dari nilai elemen:

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]**

Untuk berbagai objek:

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}]**
Umesh
sumber
2

Memperbarui! Gulir ke bawah jawaban untuk smartSortaditif prop yang memberikan lebih banyak kesenangan!
Urutkan array apa saja !

Bentuk favorit pribadi saya dari fungsi ini memungkinkan param untuk Ascending, atau Descending:

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)
    }
};

Penggunaan sesederhana:

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


Atau Contoh Cuplikan Kode Di Sini!

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')

Sekarang bersenang-senanglah dengan metode pengurutan yang mengurutkan array yang penuh dengan banyak item! Saat ini tidak mencakup "asosiatif" (alias, kunci string), tetapi mencakup semua jenis nilai! Tidak hanya akan mengurutkan beberapa nilai ascatau descsesuai, tetapi juga akan mempertahankan "posisi" konstan dari "kelompok" nilai. Dengan kata lain; int selalu pertama, lalu datang string, lalu array (ya, saya membuat multidimensi ini!), lalu Objects (tanpa filter, elemen, tanggal), & akhirnya undefined dan null!

"Mengapa?" Anda bertanya. Kenapa tidak!

Sekarang hadir dalam 2 rasa! Yang pertama membutuhkan browser yang lebih baru karena menggunakan Object.definePropertyuntuk menambahkan metode ke Array.protoypeObject. Hal ini memungkinkan untuk kemudahan alami digunakan, seperti: myArray.smartSort('a'). Jika Anda perlu menerapkan untuk browser lama, atau Anda tidak suka memodifikasi Objek asli, gulir ke bawah ke versi Metode Saja .

/* 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')


Gunakan itu sederhana! Pertama buat beberapa array gila seperti:

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' });

Maka cukup urutkan saja!

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

Hanya Metode

Sama seperti sebelumnya, kecuali hanya sebagai metode sederhana!

/* 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 */

Menggunakan:

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

Metode jsFiddle smartSort (Array, "asc | desc")

SpYk3HH
sumber
2

Coba kode ini:

HTML:

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

Kode JavaScript:

<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>
Sunny SM
sumber
2

Coba kode ini seperti di bawah ini

var a = [5, 17, 29, 48, 64, 21];
function sortA(arr) {
return arr.sort(function(a, b) {
return a - b;
})
;} 
alert(sortA(a));
pengguna7125929
sumber
apakah itu tidak benar
user7125929
1
var numArray = [140000, 104, 99];
numArray = numArray.sort((a,b) => a-b);
alert(numArray)
Vardaman PK
sumber
4
Selamat datang di StackOverflow. Jawaban Anda identik dengan jawaban yang diterima. Bisakah Anda menambahkan penjelasan pada jawaban Anda untuk mengatakan mengapa ini lebih disukai daripada jawaban yang diterima?
Simply Ged
1

Meskipun tidak diperlukan dalam JavaScript, jika Anda ingin mengembalikan -1, 0, atau 1 secara ketat (mirip dengan cara operator pesawat ruang angkasa bekerja di PHP), maka Anda dapat menggunakannya .sort() compareFunctionMath.sign()

Di compareFunctionbawah ini secara ketat mengembalikan -1, 0, atau 1:

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

Catatan: Math.sign() tidak didukung di Internet Explorer.

Grant Miller
sumber
0

Ini adalah solusi yang sudah diajukan dan diterima sebagai metode pada prototipe Array:

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

Metode sort mengubah elemen-elemen Array menjadi string. Jadi, cara di bawah ini juga berfungsi dengan baik dengan angka desimal dengan elemen array.

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

Dan memberi Anda hasil yang diharapkan.

Anshul Chaurasia
sumber
0

Mengganti metode pengurutan.

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]
pasir
sumber
0

Fungsi sortir default adalah sortir dalam urutan kamus:

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

Yang di atas bukan kasus yang kita inginkan untuk angka. Jadi, jika Anda memiliki bilangan bulat dan fungsi pengurutan default tidak berfungsi (karena mengurutkan dalam urutan kamus) maka Anda harus mengimplementasikan fungsi Anda sendiri:

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]

Saya harap Anda memiliki pertanyaan dalam benaknya bagaimana cara kerjanya? Di sini, ketika kami menyediakan metode dalam fungsi sortir, ia melewati dua angka setiap kali dan jika angka itu kembali

  • Nilai -ve atau 0, itu membuat nomor pertama di tempatnya
  • + sudah menghargai itu menukar tempat.

Dengan mengikuti ini untuk semua angka itu mengurutkan array bilangan bulat.

Jika Anda menggunakan ES6 maka tulis fungsi panah:

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

Berikut ini adalah fungsi susunan array saya di perpustakaan utils:

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]
firestoke
sumber
3
Ini salah! fungsi sort perlu mengembalikan angka negatif, 0 atau positif, tidak benar atau salah.
jperelli
Seperti @jperelli telah sebutkan, fungsi sortir membutuhkan angka, bukan boolean, untuk dikembalikan (dan mengingat bagaimana ada 3 kemungkinan status, sama, di atas, dan di bawah, ini diperlukan untuk memiliki sortir yang stabil). Seperti jawaban Anda dinyatakan, itu tidak berhasil. a-bharus digunakan sebagai gantinya. (Anda bisa menyukai dan melakukan Number(a>b)-0.5, namun itu masih belum stabil).
ecc521