Як правильно сортувати масив цілих чисел


846

Спроба отримати найвище і найнижче значення з масиву, який, наскільки я знаю, містить лише цілі числа, здається складніше, ніж я думав.

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

Я очікую, що це покаже 99, 104, 140000. Натомість це показує 104, 140000, 99. Таким чином, схоже, сортування обробляє значення як рядки.

Чи є спосіб отримати функцію сортування фактично сортувати за цілим значенням?


10
Зауважте, що жоден з найвищих відповідей не відповідає правильним значенням з усіма значеннями з плаваючою комою; зокрема, ніхто з них не справляється NaN. Було б добре побачити високо оцінену відповідь, яка стосується NaN.
Quuxplusone

3
До речі, якщо ви сортуєте безліч та безліч цілих чисел, переваги буде використовувати алгоритм сортування цілих чисел, наприклад, підрахунок сортування . Сортування часу підрахунку часу займе лінійно запускати ваги з розміром масиву: O (n). Тоді як усі рішення тут використовують порівняльний сорт, який є менш ефективним: O (n * log n).
Web_Designer

1
@Web_Designer Сортування лінійне щодо діапазону чисел, а не масиву. Наприклад, сортування [1,1000000] займе більше двох кроків, оскільки алгоритму доведеться сканувати кожен індекс масиву від 1 до 1000000, щоб побачити значення комірки більше 0.
yters

2
@yters Використовуючи хешмап, ви можете звернути увагу лише на цілі числа, які відображаються в сортованому масиві. Це робить сортування лінійним wrt розміром масиву.
Кевін

1
найшвидший спосіб полягає у використанні ізоморфного модуля сортування масиву, який працює в обох веб-переглядачах і на вузлі, підтримуючи будь-який тип введення, обчислювані поля та замовлення на замовлення.
Ллойд

Відповіді:


1233

За замовчуванням метод сортування сортує елементи за алфавітом. Щоб сортувати число, просто додайте новий метод, який обробляє числові сорти (sortNumber, показаний нижче) -

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

console.log(numArray);

У ES6 ви можете спростити це за допомогою стрілочних функцій:

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

Документація:

Mozilla Array.prototype.sort()рекомендує цю функцію порівняння для масивів, які не містять Infinity або NaN. (Тому що Inf - Infце NaN, а не 0).

Також приклади сортування об'єктів за ключами.


148
Приємно. Але чи дійсно немає нестандартного способу отримати числовий сорт із JavaScript?
peirix

39
а-а-а, це поза коробкою! Але якщо ви насправді непрактичні, ви можете прив’язати функції до класу класу масиву на самому початку вашого JavaScript: // Array.prototype.sortNormal = function () {return this.sort (function (a, b) {return a - b})} // Тепер виклик .sortNormal () на будь-який масив буде сортувати його за чисельністю
Джек Францен

13
Чому ab, а не a> b. Я пропоную останню, щоб уникнути помилок роботи машини
Лука Даванцо

35
@Velthune Функція порівняння повинна повертати -1, 0 або +1. a> b поверне лише істинне або хибне.
Іван Перес

48
Цей код можна скоротити за допомогою функції стрілки . numberArray.sort((a, b) => (a - b));Так! Я думаю, що це близько до нестандартного способу. Примітка. Перевірте, чи підтримує ваш двигун JS функції стрілок.
Константин Ван

173

Тільки спираючись на всі вищезазначені відповіді, їх також можна виконати в одному рядку, як це:

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 Виправлено: var arr = [140000, 104, 99].sort(function(a,b) { return a-b; });. Або більш компактно, в ES6let arr = [140000, 104, 99].sort((a,b) => a-b);
00500005

1
Як я вже говорив у коментарі вище, функції стрілок тут погано підходять, і я б заважав комусь використовувати їх таким чином. Ви використовуєте побічний ефект синтаксису стрілки для вирізання слів functionі return, але насправді не використовуєте справжню мету передачі функції стрілки this. Цей код означає, що відбувається певний thisконтекст, але немає. Заплутати інших розробників для читання вашого коду, лише щоб зберегти кілька символів. Не залежати від побічних ефектів - код з метою!
бамбук

12
@bambery Я не думаю, що вам потрібно використовувати функцію стрілки виключно для зміни контексту ...
Тед Морін,

7
@bambery, ви насправді неправильно розумієте, що робить функція стрілки. Ви думаєте, що це якось переходить thisу функцію, але це неправда. Він фактично нехтує створенням thisі argumentsзмінної, яка зазвичай перезаписує батьківські змінні. Єдина причина, яку ви можете використовувати thisвсередині функції стрілки, - це лексичне визначення обсягу.
cuth

2
@bambery, яка не старіла ... три роки потому і сучасна розробка JavaScript використовує функції стрілок майже виключно. :)
Кіп

71

array.sort робить лексикографічне сортування за замовчуванням, а для числового сортування надають власну функцію. Ось простий приклад:

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

numArray.sort(compareNumbers);

Також зауважте, що сортування працює "на місці", у призначенні немає потреби.


Я не зрозумів вище код, як "return a - b" виконує сортування за зростанням?
vikramvi

якщо a <b, CompareNumbers повертає від’ємне число. Якщо a> b, це буде додатним. Якщо дорівнює, вона повертається 0.
Пол Діксон

38

Ця відповідь еквівалентна деяким із існуючих відповідей, але функції стрілок ECMAScript 6 забезпечують набагато більш компактний синтаксис, що дозволяє нам визначити функцію впорядкування вбудованого типу без шкоди для читабельності:

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

Сьогодні він підтримується в більшості браузерів .


1
"без шкоди для читабельності". Це суб'єктивно. З деякими простими цілими числами це читається. Коли ви працюєте зі складнішими об'єктами і хочете сортувати властивість, не так вже й багато.
Трістан

3
@Tristan, сортування за властивістю об'єкта все ще можна зробити досить чисто, використовуючи цей синтаксис. Якщо властивість об'єкта, на який ви хочете сортувати, - це число, яке ви можете зробити: objArray=objArray.sort((a,b)=>a.numProperty - b.numProperty);а якщо властивість - це рядок, який ви можете зробити: Після objArray=objArray.sort((a,b)=>a.strProperty.localeCompare(b.strProperty))‌​;цього, це питання спеціально задає питання про сортування масиву цілих чисел
jjjjs

34

Я здивований, чому всі рекомендують передати функцію порівняння sort(), що робить сортування дуже повільним!

Для сортування чисел просто створіть будь-який TypedArray :

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


4
Використання TypedArray прискорює сортування приблизно в 5 разів. Якщо ви хочете пройти ще швидше hpc-алгоритми, пакет npm реалізує сортування Radix Sort and Counting Sort, що пропонує кілька відповідей тут.
DragonSpit

вау, не знав, що це існує!
pixelearth

21

Причина, чому функція сортування поводиться так дивно

З документації :

[...] масив сортується відповідно до значення точки коду Unicode кожного символу відповідно до перетворення рядків кожного елемента.

Якщо ви надрукуєте значення масиву unicode точки масиву, це стане зрозумілим.

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

Це повертається: "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)

Тепер, оскільки 140000 та 104 повернули однакові значення (49), він скорочує перший індекс і перевіряє знову:

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)

Якщо ми відсортуємо це, то отримаємо:

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

тому 104 приходить до 140000.

Отже, кінцевим результатом буде:

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

104, 140000, 99

Висновок:

sort()робить сортування, лише переглядаючи перший індекс чисел. sort()не байдуже, чи ціле число більше, ніж інше, воно порівнює значення унікоду цифр, а якщо є два рівні значення однокодування, то він перевіряє, чи є наступна цифра, і порівнює це також.

Щоб правильно сортувати, ви повинні пройти функцію порівняння, sort()як описану тут .


Підказка: Це лише моє пояснення, я насправді не шукав код. Тому не варто повністю довіряти цій відповіді.
Чорний

17

Я згоден з aks, однак замість використання

return a - b;

Ви повинні використовувати

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

18
Чи можете ви пояснити, чому хтось повинен використовувати вашу більш нечитабельну потрійну операцію? Наскільки я можу сказати, це матиме такий же результат.
stefannew

6
Ця відповідь також враховує рівні значення і залишає їх на тому самому місці.
Maarten00

23
А а - б не?
Брайан Рейнер

12
"return ab" може бути адекватним для конкретного випадку цього питання (javascript, і всі елементи введення, відомі як ints), але особисто я віддаю перевагу потрійній формі, оскільки вона є більш канонічною - вона працює в більшості випадків, у більшості мов програмування , з більшою кількістю типів даних. Наприклад, C, ab може переповнюватись, що призводить до нескінченного циклічного циклу, пошкодження пам’яті, збоїв і т.д.
Дон Хатч

8
The >і <все ще порівнюють a і b як рядки.
vriesdemichael

11

У новому світі ES6 подібне зробити набагато простіше

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

Це все, що вам потрібно :)


10

У JavaScript поведінка методу sort () за замовчуванням полягає в сортуванні значень у масиві за алфавітом.

Для сортування за номером потрібно визначити числову функцію сортування (що дуже просто):

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

numArray = numArray.sort(sortNumber);

8

Array.prototype.sort () - це спосіб перейти до сортування масивів, але є кілька питань, про які нам слід знати.

Порядок сортування за замовчуванням лексикографічний, а не числовий, незалежно від типів значень у масиві. Навіть якщо масив - це всі числа, всі значення будуть перетворені в рядкові та відсортовані лексикографічно.

Отже, чи потрібно нам налаштувати метод sort () та reverse (), як показано нижче.

Посилана URL-адреса

Для сортування чисел всередині масиву

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

Для реверсування чисел всередині масиву

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

Посилана URL-адреса


6

На питання вже відповіли, найкоротший спосіб - це використовувати sort()метод. Але якщо ви шукаєте більше способів сортування масиву чисел, а також любите цикли, перевірте наступне

Сортування вставки

Зростання:

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

Спад:

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

Сортування вибору:

Зростання:

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

Спад:

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

Весело


Чи є справді швидше для крихітних масивів, ніж використання sort()на TypedArray, як пропонує ця відповідь . Звичайно, вони не будуть швидшими для середніх і великих масивів, оскільки це алгоритми O (n ^ 2).
Пітер Кордес

5

Функція "чисельно" нижче служить метою сортування масиву чисел чисельно в багатьох випадках, коли вони надаються як функція зворотного виклику:

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

array.sort(numerically); 

Але в деяких рідкісних випадках, коли масив містить дуже великі та негативні числа, може виникнути помилка переповнення, оскільки результат ab стає меншим за найменше число, з яким JavaScript може впоратися.

Тож кращий спосіб написання функції числення полягає в наступному:

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

1
Номери JavaScript є плаваючою комою. IEEE754 визначає правила переповнення та переливу, включаючи переповнення до + -бесконечності та перелив до субнормальних або + -0,0. Я не думаю, що віднімання двох чисел може перевищувати + -0,0, навіть якщо вони великі і поблизу рівні. Різниця між двома дублями завжди представлена ​​як інший ненульовий подвійний (якщо тільки він не переповнює, як DBL_MIN - DBL_MAX), але переповнення неможливо. Катастрофічне скасування робить результат неточним, втрачаючи більшість своїх "значущих цифр", але a-bзавжди буде ненульовим і матиме правильний знак для! = B.
Пітер Кордес

4

для обробки undefined, null та NaN: Null поводиться як 0, NaN та undefined йде до кінця.

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

Лише для звичайного масиву значень елементів:

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

Для масиву об'єктів:

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

Оновлення! Прокрутіть донизу відповідь на smartSortдобавку, яка забезпечує ще більше задоволення!
Сортує масиви нічого !

Моя особиста улюблена форма цієї функції дозволяє отримати параметр «Зростання або Зростання»:

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

Використання просте, як:

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


Або Приклад фрагменту коду тут!

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

Тепер отримайте ще більше задоволення від методу сортування, який сортує масив, повний кількох елементів! Наразі не охоплює "асоціативний" (він же, рядкові клавіші), але він охоплює кожен тип значень! Він не тільки буде сортувати декілька значень ascабо descвідповідно, але й підтримуватиме постійне "положення" "груп" значень. Іншими словами; ints - це завжди спочатку, потім надходять рядки, потім масиви (так, я роблю це багатовимірний!), потім об'єкти (нефільтроване, елемент, дата) та нарешті невизначені та нульові значення!

"Чому?" Ви запитаєте. Чому ні!

Зараз випускається 2 аромати! Перший з них вимагає нових браузерів, оскільки він використовує Object.definePropertyдля додавання методу до Array.protoypeObject. Це дозволяє спростити природне використання, такі як: myArray.smartSort('a'). Якщо вам потрібно реалізувати для старих веб-переглядачів або вам просто не подобається змінювати нативні об’єкти, перейдіть до версії Only Method .

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


Використання просто! Спочатку зробіть якийсь божевільний масив на кшталт:

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

Тоді просто сортуйте!

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

Тільки метод

Те саме, що і попередній, за винятком лише простого методу!

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

Використання:

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

Метод jsFiddle smartSort (масив, "asc | desc")


2

Спробуйте цей код:

HTML:

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

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

Спробуйте цей код, як показано нижче

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

це неправда?
user7125929

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

4
Ласкаво просимо до StackOverflow. Ваша відповідь ідентична прийнятій відповіді. Чи можете ви додати якісь пояснення до своєї відповіді, щоб сказати, чому це слід віддати перевагу над прийнятою відповіддю?
Просто Гед

1

Хоча це не потрібно в JavaScript, якщо ви хочете, щоб строго повертати -1, 0 або 1 (подібно до того, як працює оператор космічного корабля в PHP), ви можете використовувати .sort() compareFunctionMath.sign()

compareFunctionНижче строго повертає -1, 0 або 1:

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

Примітка: Math.sign() не підтримується в Internet Explorer.


0

Це вже запропоноване та прийняте рішення як метод прототипу масиву:

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

0

Як метод сортування перетворює елементи масиву в рядок. Отже, нижче спосіб також добре працює з десятковими числами з елементами масиву.

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

І дає очікуваний результат.


0

Переосмислення методу сортування.

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

Функція сортування за замовчуванням сортується у порядку словника:

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

Наведене вище не так, як ми хочемо для чисел. Отже, якщо у вас є цілі числа, а функція сортування за замовчуванням не працює (тому що вона сортується в порядку словника), то вам доведеться реалізувати власну функцію:

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]

Сподіваюся, у вас є питання про те, як це працює? Тут, коли ми надаємо метод функції сортування, він щоразу передає два числа, і якщо число повертається

  • -ve значення або 0, він зберігає перше число на своєму місці
  • + Ви цінуєте, що він обмінює місце.

Дотримуючись цього для всіх чисел, він сортує масив цілих чисел.

Якщо ви використовуєте ES6, тоді напишіть функцію стрілки:

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

-1

Ось моя функція масиву сортування в бібліотеці утиліт:

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
Це явно неправильно! Функція сортування повинна повертати від'ємні, 0 або додатні числа, а не істинні чи помилкові.
jperelli

Як зазначав @jperelli, функція сортування потребує повернення числа, а не булевого (і враховуючи, як існують 3 можливі стани, рівні, вгорі та внизу, це необхідно для стабільного сортування). Як зазначено у вашій відповіді, це не працює. a-bслід використовувати замість цього. (Ви можете пофантазувати і зробити Number(a>b)-0.5, однак це все ще не стійкий сорт).
ecc521
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.