Cách sắp xếp một mảng các số nguyên một cách chính xác


848

Cố gắng để có được giá trị cao nhất và thấp nhất từ ​​một mảng mà tôi biết sẽ chỉ chứa các số nguyên dường như khó hơn tôi nghĩ.

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

Tôi hy vọng điều này sẽ hiển thị 99, 104, 140000. Thay vào đó nó cho thấy 104, 140000, 99. Vì vậy, có vẻ như sắp xếp xử lý các giá trị dưới dạng chuỗi.

Có cách nào để có được hàm sắp xếp để thực sự sắp xếp trên giá trị nguyên không?


10
Lưu ý rằng không có câu trả lời hàng đầu nào xử lý chính xác tất cả các giá trị dấu phẩy động; đặc biệt, không ai trong số họ xử lý NaN. Sẽ thật tuyệt khi thấy một câu trả lời được xếp hạng cao liên quan đến NaN.
Quuxplusone

3
BTW, nếu bạn sắp xếp nhiều và nhiều số nguyên, sẽ là lợi thế khi sử dụng thuật toán sắp xếp số nguyên như sắp xếp đếm . Sắp xếp thời gian đếm sẽ mất để chạy quy mô tuyến tính với kích thước của mảng của bạn: O (n). Trong khi đó tất cả các giải pháp ở đây đều sử dụng sắp xếp so sánh kém hiệu quả hơn: O (n * log n).
Web_Designer

1
@Web_Designer Sắp xếp đếm là tuyến tính liên quan đến phạm vi số, không phải mảng. Ví dụ: sắp xếp [1.1000000] sẽ mất hơn 2 bước, vì thuật toán sẽ phải quét từng chỉ số mảng trong khoảng từ 1 đến 1000000 để xem giá trị nào của ô lớn hơn 0.
yters 13/2/18

2
@yters Sử dụng hàm băm, bạn chỉ có thể chú ý đến các số nguyên hiển thị trong mảng được sắp xếp. Điều này làm cho sắp xếp tuyến tính wrt kích thước mảng.
Kevin

1
cách nhanh nhất là sử dụng mô đun mảng sắp xếp đẳng cấu , hoạt động tự nhiên trong cả trình duyệt và nút, hỗ trợ mọi loại đầu vào, trường được tính toán và thứ tự sắp xếp tùy chỉnh.
Lloyd

Câu trả lời:


1236

Theo mặc định, phương pháp sắp xếp sắp xếp các thành phần theo thứ tự abc. Để sắp xếp số, chỉ cần thêm một phương thức mới xử lý các loại số (sortNumber, hiển thị bên dưới) -

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

console.log(numArray);

Trong ES6, bạn có thể đơn giản hóa điều này bằng các hàm mũi tên:

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

Tài liệu:

Mozilla Array.prototype.sort()khuyến nghị chức năng so sánh này cho các mảng không chứa Infinity hoặc NaN. (Vì Inf - Inflà NaN, không phải 0).

Ngoài ra các ví dụ về sắp xếp các đối tượng theo khóa.


148
Đẹp. Nhưng có thực sự không có cách nào khác để có được một loại số từ javascript?
peirix

39
ahah đây là ra khỏi hộp! Nhưng nếu bạn thực sự không thực tế, bạn có thể liên kết các hàm với lớp lớp mảng ngay từ đầu javascript: // Array.prototype.sortN normal = function () {return this.sort (function (a, b) {return a - b})} // Bây giờ gọi .sortN normal () trên bất kỳ mảng nào sẽ sắp xếp nó theo số
Jack Franzen

13
Tại sao ab và không a> b. Tôi đề nghị cái cuối cùng để tránh lỗi máy hoạt động
Luca Davanzo

35
@Velthune Hàm so sánh sẽ trả về -1, 0 hoặc +1. a> b sẽ chỉ trả về đúng hay sai.
Iván Pérez

48
Mã này có thể được rút ngắn bằng cách sử dụng Chức năng Mũi tên . numberArray.sort((a, b) => (a - b));Yay! Tôi nghĩ rằng điều này gần với cách thức bên ngoài. Lưu ý: kiểm tra xem công cụ JS của bạn có hỗ trợ Chức năng Mũi tên không.
Toàn cảnh

174

Chỉ cần dựa trên tất cả các câu trả lời trên, chúng cũng có thể được thực hiện trong một dòng như thế này:

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
@bodyflex Đã sửa : var arr = [140000, 104, 99].sort(function(a,b) { return a-b; });. Hoặc gọn hơn, trong ES6let arr = [140000, 104, 99].sort((a,b) => a-b);
00500005

1
Như tôi đã nói trong một nhận xét ở trên, các chức năng mũi tên rất phù hợp ở đây và tôi sẽ không khuyến khích bất cứ ai sử dụng chúng theo cách này. Bạn đang sử dụng một hiệu ứng phụ của cú pháp mũi tên để cắt các từ functionreturn, nhưng thực tế không sử dụng mục đích thực sự của hàm mũi tên this. Mã này ngụ ý có một số thisbối cảnh đi qua xảy ra, nhưng không có. Nhầm lẫn cho các nhà phát triển khác đọc mã của bạn, chỉ để lưu một vài ký tự. Đừng phụ thuộc vào tác dụng phụ - mã với mục đích!
bambery

12
@bambery Tôi không nghĩ rằng bạn cần sử dụng chức năng mũi tên dành riêng cho việc thay đổi bối cảnh trên sàn
Ted Morin

7
@bambery, bạn thực sự hiểu nhầm chức năng mũi tên đang làm gì. Bạn nghĩ rằng bằng cách nào đó nó đi thisvào chức năng nhưng điều đó không đúng. Nó thực sự bỏ qua việc tạo một thisargumentsbiến thường ghi đè lên các biến cha. Lý do duy nhất bạn có thể sử dụng thisbên trong một hàm mũi tên là phạm vi từ vựng.
cuth

2
@bambery không đủ tuổi ... ba năm sau và phát triển javascript hiện đại sử dụng các chức năng mũi tên gần như độc quyền. :)
Kip

71

Array.sort thực hiện sắp xếp từ vựng theo mặc định, đối với sắp xếp số, cung cấp chức năng của riêng bạn. Đây là một ví dụ đơn giản:

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

numArray.sort(compareNumbers);

Cũng lưu ý rằng sắp xếp hoạt động "tại chỗ", không cần chuyển nhượng.


Tôi không hiểu mã ở trên, làm thế nào để "return a - b" sắp xếp tăng dần?
vikramvi

nếu a <b, so sánhNumbers trả về số âm. Nếu a> b, nó sẽ dương. Nếu bằng nhau, nó trả về 0.
Paul Dixon

38

Câu trả lời này tương đương với một số câu trả lời hiện có, nhưng các hàm mũi tên ECMAScript 6 cung cấp một cú pháp nhỏ gọn hơn nhiều cho phép chúng ta xác định một hàm sắp xếp nội tuyến mà không phải hy sinh khả năng đọc:

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

Nó được hỗ trợ trong hầu hết các trình duyệt hiện nay .


1
"Không hy sinh khả năng đọc". Đây là chủ quan. Với một số số nguyên đơn giản, nó có thể đọc được. Khi làm việc với các đối tượng phức tạp hơn và bạn muốn sắp xếp trên một thuộc tính, không quá nhiều.
Tristan

3
@Tristan, việc sắp xếp thuộc tính của một đối tượng vẫn có thể được thực hiện khá sạch sẽ bằng cú pháp này. Nếu thuộc tính của đối tượng bạn muốn sắp xếp là một số bạn có thể làm: objArray=objArray.sort((a,b)=>a.numProperty - b.numProperty);và nếu thuộc tính là một chuỗi bạn có thể làm: objArray=objArray.sort((a,b)=>a.strProperty.localeCompare(b.strProperty))‌​;Điều đó đã được nói, câu hỏi này đặc biệt hỏi về cách sắp xếp một mảng các số nguyên
jjjjs

34

Tôi ngạc nhiên tại sao mọi người đề nghị vượt qua một funciton so sánh để sort() , điều đó làm cho việc sắp xếp thực sự chậm!

Để sắp xếp số, chỉ cần tạo bất kỳ TypedArray :

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


4
Sử dụng TypedArray tăng tốc sắp xếp khoảng 5 lần. Nếu bạn muốn đi nhanh hơn nữa, gói npm của thuật toán hpc thực hiện sắp xếp Radix Sắp xếp và Đếm mà một số câu trả lời ở đây gợi ý.
DragonSpit

wow, không biết điều này tồn tại!
pixelearth

21

Lý do tại sao chức năng sắp xếp hành xử rất kỳ lạ

Từ tài liệu :

[...] Mảng được sắp xếp theo giá trị điểm mã Unicode của từng ký tự, theo chuyển đổi chuỗi của từng thành phần.

Nếu bạn in các giá trị điểm unicode của mảng thì nó sẽ rõ ràng.

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

Điều này trả về: "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)

Bây giờ, vì 140000 và 104 trả về cùng một giá trị (49), nó cắt chỉ mục đầu tiên và kiểm tra lại:

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)

Nếu chúng ta sắp xếp thứ này, thì chúng ta sẽ nhận được:

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

vì vậy 104 đến trước 140000.

Vì vậy, kết quả cuối cùng sẽ là:

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

104, 140000, 99

Phần kết luận:

sort() không sắp xếp bằng cách chỉ nhìn vào chỉ số đầu tiên của các số. sort()không quan tâm nếu một số nguyên lớn hơn số khác, nó so sánh giá trị của unicode của các chữ số và nếu có hai giá trị unicode bằng nhau, thì nó sẽ kiểm tra xem có một chữ số tiếp theo không và so sánh nó.

Để sắp xếp chính xác, bạn phải chuyển một hàm so sánh sort()như được giải thích ở đây .


Gợi ý: Đây chỉ là lời giải thích của tôi, tôi đã không thực sự tra cứu mã. Vì vậy, đừng hoàn toàn tin tưởng câu trả lời này.
Đen

17

Tôi đồng ý với aks, tuy nhiên thay vì sử dụng

return a - b;

Bạn nên sử dụng

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

18
Bạn có thể giải thích lý do tại sao bất cứ ai nên sử dụng hoạt động ternary khó đọc hơn của bạn? Theo như tôi có thể nói nó sẽ có kết quả tương tự.
stefannew

6
Câu trả lời này cũng xem xét các giá trị bằng nhau và để chúng ở cùng một nơi.
Maarten00

23
Và a - b không?
Bryan Rayner

12
"return ab" có thể phù hợp với trường hợp cụ thể của câu hỏi này (javascript và tất cả các mục đầu vào được gọi là ints), nhưng cá nhân tôi thích hình thức ternary hơn vì nó hợp quy hơn - nó hoạt động trong nhiều trường hợp hơn, trong nhiều ngôn ngữ lập trình hơn , với nhiều loại dữ liệu hơn. Ví dụ, trong C, ab có thể tràn, dẫn đến sắp xếp vòng lặp vô tận, bộ nhớ bị hỏng, bị hỏng, v.v. Điều đó nói rằng, ngay cả hình thức ternary sẽ không hoạt động hoàn toàn nếu có NaN hoặc các loại hỗn hợp liên quan.
Don nở

8
Các ><vẫn so sánh a và b như dây đàn.
vriesdemichael

11

Trong thế giới ES6 mới, việc sắp xếp dễ dàng hơn nhiều

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

Đó là tất cả những gì bạn cần :)


10

Trong JavaScript, hành vi mặc định của phương thức sort () là sắp xếp các giá trị trong một mảng theo thứ tự bảng chữ cái.

Để sắp xếp theo số, bạn phải xác định hàm sắp xếp số (rất dễ):

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

numArray = numArray.sort(sortNumber);

8

Array.prototype.sort () là phương thức đi tới để sắp xếp các mảng, nhưng có một vài vấn đề chúng ta cần phải biết.

Thứ tự sắp xếp theo từ điển mặc định và không phải là số bất kể các loại giá trị trong mảng. Ngay cả khi mảng là tất cả các số, tất cả các giá trị sẽ được chuyển đổi thành chuỗi và được sắp xếp theo từ vựng.

Vì vậy, chúng ta nên tùy chỉnh phương thức sort () và Reverse () như dưới đây.

URL giới thiệu

Để sắp xếp các số bên trong mảng

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

Để đảo ngược số bên trong mảng

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

URL giới thiệu


6

Câu hỏi đã được trả lời, cách ngắn nhất là sử dụng sort() phương pháp. Nhưng nếu bạn đang tìm kiếm nhiều cách hơn để sắp xếp mảng số của mình và bạn cũng thích chu kỳ, hãy kiểm tra các mục sau

Sắp xếp chèn

Tăng dần:

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

Giảm dần:

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

Lựa chọn sắp xếp:

Tăng dần:

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

Giảm dần:

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

Chúc vui vẻ


Có ai trong số này thực sự nhanh hơn cho các mảng nhỏ hơn so với sử dụng sort()trên TypedArray như câu trả lời này gợi ý . Chắc chắn chúng sẽ không nhanh hơn đối với các mảng từ trung bình đến lớn vì đây là các thuật toán O (n ^ 2).
Peter Cordes

5

Hàm 'số' dưới đây phục vụ mục đích sắp xếp mảng số trong nhiều trường hợp khi được cung cấp dưới dạng hàm gọi lại:

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

array.sort(numerically); 

Nhưng trong một số trường hợp hiếm hoi, trong đó mảng chứa số rất lớn và số âm, lỗi tràn có thể xảy ra do kết quả của ab nhỏ hơn số nhỏ nhất mà JavaScript có thể xử lý.

Vì vậy, một cách tốt hơn để viết hàm số như sau:

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

1
Số JavaScript là dấu phẩy động. IEEE754 định nghĩa các quy tắc tràn và tràn, bao gồm tràn đến + -Infinity và dưới mức không bình thường hoặc + -0.0. Tôi không nghĩ phép trừ hai số có thể vượt quá + -0.0 ngay cả khi cả hai số lớn và gần bằng nhau. Sự khác biệt giữa hai nhân đôi luôn có thể được biểu diễn dưới dạng một số khác không (trừ khi nó tràn ra, như thế DBL_MIN - DBL_MAX) nhưng không thể thực hiện được. Hủy bỏ thảm khốc làm cho kết quả không chính xác, mất hầu hết các "chữ số có nghĩa", nhưng a-bsẽ luôn luôn khác không và có dấu hiệu đúng cho a! = B.
Peter Cordes

4

để xử lý không xác định, null và NaN: Null hoạt động như 0, NaN và không xác định sẽ kết thúc.

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

Đối với một mảng bình thường chỉ có các giá trị phần tử:

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

Đối với một mảng các đối tượng:

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

Cập nhật! Cuộn xuống cuối câu trả lời cho smartSortphụ gia prop mang lại nhiều niềm vui hơn nữa!
Sắp xếp mảng của bất cứ điều gì !

Hình thức yêu thích cá nhân của tôi về chức năng này cho phép tham số tăng dần hoặc giảm dần:

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

Cách sử dụng đơn giản như:

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


Hoặc Mã Đoạn Ví dụ ở đây!

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

Bây giờ thậm chí còn vui hơn với một phương pháp sắp xếp sắp xếp một mảng đầy đủ nhiều mục! Hiện tại không bao gồm "liên kết" (còn gọi là khóa chuỗi), nhưng nó bao gồm mọi loại giá trị! Nó không chỉ sắp xếp nhiều giá trị aschoặcdesc theo đó, mà còn duy trì "vị trí" không đổi của "nhóm" các giá trị. Nói cách khác; int luôn luôn là đầu tiên, sau đó đến chuỗi, sau đó là mảng (vâng, tôi đang tạo ra đa chiều này!), sau đó các Đối tượng (chưa được lọc, phần tử, ngày), và cuối cùng không xác định và null!

"Tại sao?" bạn hỏi. Tại sao không!

Bây giờ đến trong 2 hương vị! Cái đầu tiên yêu cầu các trình duyệt mới hơn vì nó sử dụng Object.definePropertyđể thêm phương thức vào Array.protoypeObject. Điều này cho phép dễ dàng sử dụng tự nhiên , chẳng hạn như : myArray.smartSort('a'). Nếu bạn cần triển khai cho các trình duyệt cũ hơn hoặc đơn giản là bạn không thích sửa đổi Đối tượng gốc, hãy cuộn xuống phiên bản Chỉ phương thức .

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


Sử dụng rất đơn giản! Đầu tiên tạo một số mảng điên rồ như:

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

Sau đó, chỉ cần sắp xếp nó!

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

Phương pháp chỉ

Tương tự như trước, ngoại trừ chỉ là một phương pháp đơn giản!

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

Sử dụng:

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

Phương thức jsFiddle smartSort (Mảng, "asc | desc")


2

Hãy thử mã này:

HTML:

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

Mã 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>

2

Hãy thử mã này như dưới đây

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

Có phải vậy không?
dùng7125929

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

4
Chào mừng bạn đến với StackOverflow. Câu trả lời của bạn giống hệt với câu trả lời được chấp nhận. Bạn có thể thêm bất kỳ lời giải thích nào cho câu trả lời của bạn để nói tại sao điều này nên được ưu tiên hơn câu trả lời được chấp nhận không?
Đơn giản là Ged

1

Mặc dù không bắt buộc trong JavaScript, nếu bạn muốn hoàn toàn trả về -1, 0 hoặc 1 (tương tự như cách toán tử tàu vũ trụ hoạt động trong PHP), thì bạn có thể sử dụng .sort() compareFunctionMath.sign()

Dưới compareFunctionđây hoàn toàn trả về -1, 0 hoặc 1:

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

Lưu ý: Math.sign() không được hỗ trợ trong Internet Explorer.


0

Đây là giải pháp đã được đề xuất và chấp nhận như một phương pháp trên nguyên mẫu Array:

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

0

Khi phương thức sắp xếp chuyển đổi các phần tử Array thành chuỗi. Vì vậy, cách dưới đây cũng hoạt động tốt với số thập phân với các phần tử mảng.

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

Và cung cấp cho bạn kết quả mong đợi.


0

Ghi đè phương thức sắp xếp.

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

Hàm sắp xếp mặc định được sắp xếp theo thứ tự từ điển:

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

Trên đây không phải là trường hợp chúng tôi muốn cho số. Vì vậy, nếu bạn có số nguyên và hàm sắp xếp mặc định không hoạt động (vì nó sắp xếp theo thứ tự từ điển) thì bạn phải thực hiện chức năng của riêng mình:

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]

Tôi hy vọng bạn có một câu hỏi trong đầu rằng nó hoạt động như thế nào? Ở đây khi chúng ta cung cấp một phương thức trong hàm sort, nó sẽ truyền hai số mỗi lần và nếu số đó trả về

  • -ve value hoặc 0, nó giữ số đầu tiên tại vị trí của nó
  • + ve giá trị nó trao đổi địa điểm.

Bằng cách làm theo điều này cho tất cả các số, nó sắp xếp mảng số nguyên.

Nếu bạn đang sử dụng ES6 thì hãy viết hàm mũi tên:

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

-1

Đây là hàm sắp xếp của tôi trong thư viện 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]

3
Điều này hoàn toàn sai! hàm sắp xếp cần trả về số âm, 0 hoặc dương, không đúng hoặc sai.
jperelli

Như @jperelli đã đề cập, hàm sắp xếp cần một số, không phải là boolean, để được trả về (và đưa ra cách có 3 trạng thái có thể, bằng, trên và dưới, điều này là cần thiết để có một sắp xếp ổn định). Như câu trả lời của bạn được nêu, nó không hoạt động. a-bnên được sử dụng thay thế. (Bạn có thể nhận được ưa thích và làm một Number(a>b)-0.5, tuy nhiên đó vẫn không phải là một loại ổn định).
ecc521
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.