วิธีการเรียงลำดับอาร์เรย์ของจำนวนเต็มอย่างถูกต้อง


847

พยายามรับค่าสูงสุดและต่ำสุดจากอาร์เรย์ที่ฉันรู้ว่าจะมีจำนวนเต็มเท่านั้นดูเหมือนว่าจะยากกว่าที่ฉันคิด

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

ฉันคาดหวังว่าสิ่งนี้จะแสดง 99, 104, 140000ฉันคาดหวังนี้เพื่อแสดง104, 140000, 99แต่มันแสดงให้เห็นว่า ดังนั้นดูเหมือนว่าการเรียงลำดับจะจัดการค่าเป็นสตริง

มีวิธีการรับฟังก์ชั่นการเรียงลำดับจริงตามมูลค่าจำนวนเต็ม?


10
ขอให้สังเกตว่าไม่มีคำตอบอันดับต้น ๆ ที่จัดการกับค่าทศนิยมทั้งหมดอย่างถูกต้อง; NaNโดยเฉพาะอย่างยิ่งไม่มีของพวกเขาจัดการ NaNมันจะดีจะเห็นคำตอบที่สูงอันดับที่เกี่ยวข้องกับ
Quuxplusone

3
BTW ถ้าคุณกำลังคัดแยกจำนวนมากและจำนวนของจำนวนเต็มมันจะเป็นข้อได้เปรียบที่จะใช้ขั้นตอนวิธีการจัดเรียงจำนวนเต็มเช่นการนับการจัดเรียง การเรียงลำดับการนับเวลาจะใช้ในการรันเครื่องชั่งเชิงเส้นตรงกับขนาดของอาร์เรย์ของคุณ: O (n) ในขณะที่โซลูชันทั้งหมดที่นี่ใช้การเรียงลำดับการเปรียบเทียบซึ่งมีประสิทธิภาพน้อยกว่า: O (n * log n)
Web_Designer

1
@Web_Designer การเรียงลำดับการนับเป็นเส้นตรงเกี่ยวกับช่วงตัวเลขไม่ใช่อาร์เรย์ ตัวอย่างเช่นการเรียงลำดับ [1,1000000] จะใช้เวลามากกว่า 2 ขั้นตอนเนื่องจากอัลกอริทึมจะต้องสแกนดัชนีแต่ละแถวระหว่าง 1 ถึง 1000000 เพื่อดูว่าค่าของเซลล์ใดมากกว่า 0
yters

2
@yters การใช้ hashmap คุณจะต้องใส่ใจกับจำนวนเต็มที่ปรากฏในอาร์เรย์ที่เรียงลำดับเท่านั้น ทำให้การเรียงลำดับเชิงเส้น wrt ขนาดอาร์เรย์
Kevin

1
วิธีที่เร็วที่สุดคือการใช้โมดูลเรียงลำดับ isomorphic ซึ่งทำงานได้ทั้งในเบราว์เซอร์และโหนดสนับสนุนการป้อนข้อมูลทุกประเภทฟิลด์คำนวณและคำสั่งการเรียงลำดับแบบกำหนดเอง
Lloyd

คำตอบ:


1235

โดยค่าเริ่มต้นวิธีการเรียงลำดับองค์ประกอบเรียงตามตัวอักษร ในการจัดเรียงตัวเลขเพียงเพิ่มวิธีการใหม่ที่จัดการเรียงลำดับตัวเลข (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
ดี แต่จริงๆแล้วไม่มีวิธีนอกกรอบที่จะได้รับการจัดเรียงตัวเลขจากจาวาสคริปต์หรือไม่?
peirix

39
อ่านี่มันออกมาจากกล่อง! แต่ถ้าคุณทำไม่ได้จริง ๆ คุณสามารถผูกฟังก์ชันกับคลาสอาเรย์คลาสที่จุดเริ่มต้นของ javascript: // Array.prototype.sortNormal = function () {return this.sort (function (a, b) {return a - b})} // ตอนนี้โทร. sortNormal () ในอาร์เรย์ใด ๆ จะเรียงลำดับเป็นตัวเลข
Jack Franzen

13
ทำไมต้องเป็น ab และไม่ใช่> b ฉันขอแนะนำอันสุดท้ายเพื่อหลีกเลี่ยงข้อผิดพลาดของเครื่องจักรในการดำเนินงาน
Luca Davanzo

35
@Velthune ฟังก์ชันการเปรียบเทียบควรส่งคืน -1, 0 หรือ +1 > b จะส่งกลับจริงหรือเท็จเท่านั้น
IvánPérez

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บริบทบางอย่างเกิดขึ้น แต่ไม่มี สับสนสำหรับผู้พัฒนารายอื่น ๆ ในการอ่านรหัสของคุณเพียงเพื่อประหยัดตัวอักษรสองสามตัว อย่าพึ่งผลข้างเคียง - รหัสกับวัตถุประสงค์!
bambery

12
@bambery ฉันไม่คิดว่าคุณจะต้องใช้ฟังก์ชั่นลูกศรเพื่อการเปลี่ยนแปลงบริบทโดยเฉพาะ ...
Ted Morin

7
@bambery คุณเข้าใจผิดจริง ๆ ว่าฟังก์ชั่นลูกศรกำลังทำอะไรอยู่ คุณคิดว่ามันผ่านthisเข้าไปในฟังก์ชั่น แต่ไม่เป็นความจริง มันละเลยการสร้างthisและargumentsตัวแปรที่มักจะเขียนทับตัวแปรพาเรนต์ เหตุผลเดียวที่คุณสามารถใช้thisภายในฟังก์ชั่นลูกศรคือการกำหนดขอบเขตศัพท์
คัท

2
@Bambery ที่อายุไม่ดีนัก ... สามปีต่อมาและการพัฒนาจาวาสคริปต์ที่ทันสมัยนั้นใช้ฟังก์ชั่นลูกศรโดยเฉพาะ :)
กีบ

71

array.sortทำการเรียงลำดับพจนานุกรมตามค่าเริ่มต้นสำหรับการเรียงลำดับตัวเลขให้ฟังก์ชันของคุณเอง นี่คือตัวอย่างง่ายๆ:

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

numArray.sort(compareNumbers);

นอกจากนี้โปรดทราบว่าการเรียงลำดับใช้งานได้ "ไม่จำเป็นต้องมีการมอบหมาย


ฉันไม่เข้าใจรหัสข้างต้น "คืน a - b" เรียงลำดับจากน้อยไปมากได้อย่างไร
vikramvi

ถ้า <b, comparNumber ส่งกลับจำนวนลบ ถ้า a> b มันจะเป็นค่าบวก ถ้าเท่ากับจะส่งคืน 0
Paul Dixon

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

ฉันแปลกใจว่าทำไมทุกคนแนะนำให้ส่ง funciton เปรียบเทียบไปsort()ที่ทำให้การเรียงลำดับช้ามาก!

ไปยังหมายเลขเรียงลำดับเพียงแค่สร้างใด ๆ TypedArray :

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


4
การใช้ TypedArray จะเร่งความเร็วในการจัดเรียงประมาณ 5X หากคุณต้องการใช้อัลกอริทึม hpc ที่เร็วยิ่งขึ้นแพ็กเกจ npm จะใช้ Radix Sort และ 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()ไม่สนใจว่าจำนวนเต็มมากกว่าอีกค่าใดมันทำการเปรียบเทียบค่าของ unicode ของตัวเลขและถ้ามีค่า unicode ที่เท่ากันสองค่าจากนั้นจะตรวจสอบว่ามีตัวเลขถัดไปและเปรียบเทียบด้วยหรือไม่

เพื่อจัดเรียงอย่างถูกต้องคุณต้องผ่านฟังก์ชั่นการเปรียบเทียบกับsort()เช่นอธิบายที่นี่


คำแนะนำ: นี่เป็นเพียงคำอธิบายของฉันฉันไม่ได้ค้นหารหัส ดังนั้นอย่าเชื่อใจคำตอบนี้อย่างเต็มที่
ดำ

17

ฉันเห็นด้วยกับ aks แต่แทนที่จะใช้

return a - b;

คุณควรใช้

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

18
คุณช่วยอธิบายได้ไหมว่าทำไมทุกคนควรใช้การดำเนินการแบบไตรภาคที่ไม่สามารถอ่านได้มากขึ้น? เท่าที่ฉันสามารถบอกได้ว่ามันจะมีผลเหมือนกัน
stefannew

6
คำตอบนี้ยังนำค่าที่เท่ากันมาพิจารณาและทิ้งไว้ในที่เดียวกัน
Maarten00

23
และ a - b ไม่ได้เหรอ?
Bryan Rayner

12
"return ab" อาจเพียงพอสำหรับกรณีเฉพาะของคำถามนี้ (จาวาสคริปต์และรายการอินพุตทั้งหมดที่ทราบว่าเป็น ints) แต่โดยส่วนตัวแล้วฉันชอบแบบฟอร์มที่ประกอบไปด้วยเพราะมันเป็นที่ยอมรับมากกว่า - มันทำงานได้มากกว่าในภาษาโปรแกรมเพิ่มเติม มีประเภทข้อมูลเพิ่มเติม เช่นใน C, ab สามารถล้นนำไปสู่การเรียงลำดับวนซ้ำไม่รู้จบ, ทำลายหน่วยความจำ, crashing, ฯลฯ ที่กล่าวว่าแม้รูปแบบประกอบไปด้วยจะไม่ทำงานอย่างสุขถ้ามี NaNs หรือประเภทผสมที่เกี่ยวข้อง
ดอนแฮทช์

8
>และ<ยังเปรียบเทียบและ 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);

Descending:

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

Descending:

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)
Peter Cordes

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 กำหนดกฏโอเวอร์โฟลว์และอันเดอร์โฟลว์รวมถึงโอเวอร์โฟลว์ที่ + -Infinity และอันเดอร์โฟลว์ไปยัง subnormal หรือ + -0.0 ฉันไม่คิดว่าการลบของตัวเลขสองตัวสามารถลดลงไปที่ + -0.0 แม้ว่าพวกเขาจะมีขนาดใหญ่และใกล้เคียงกันก็ตาม ความแตกต่างระหว่างสองคู่นั้นสามารถแสดงได้เหมือนคู่ที่ไม่เป็นศูนย์เสมอ (ยกเว้นว่ามีมากเกินไปเช่นDBL_MIN - DBL_MAX) แต่ไม่สามารถทำส่วนย่อยได้ การยกเลิกแบบหายนะทำให้ผลลัพธ์ไม่แน่ชัดทำให้สูญเสีย "ตัวเลขนัยสำคัญ" ส่วนใหญ่ แต่a-bจะไม่เป็นศูนย์เสมอและมีเครื่องหมายที่ถูกต้องสำหรับ! = b
Peter Cordes

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

Update! เลื่อนไปที่ด้านล่างของคำตอบเพื่อ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')

ตอนนี้สนุกยิ่งขึ้นด้วยวิธีการเรียงลำดับที่เรียงลำดับอาร์เรย์ที่เต็มไปด้วยหลายรายการ! ปัจจุบันไม่ครอบคลุม "การเชื่อมโยง" (aka, คีย์สตริง) แต่ครอบคลุมเกี่ยวกับค่าทุกประเภท! ไม่เพียง แต่จะเรียงลำดับค่าหลายค่าascหรือdescตามลำดับ แต่ยังจะรักษาค่า "ตำแหน่ง" ของ "กลุ่ม" ของค่าคงที่ กล่าวอีกนัยหนึ่ง; ints เป็นอันดับแรกเสมอจากนั้นมาสตริงจากนั้นอาร์เรย์ (ใช่ฉันทำหลายมิตินี้!) แล้ววัตถุ (ไม่กรององค์ประกอบวันที่) และในที่สุดก็ไม่ได้กำหนดและโมฆะ!

"ทำไม?" คุณถาม. ทำไมจะไม่ล่ะ!

ตอนนี้มาใน 2 รสชาติ! ครั้งแรกที่ต้องใช้เบราว์เซอร์ใหม่ที่ใช้Object.definePropertyในการเพิ่มวิธีการในArray.protoypeวัตถุ สิ่งนี้ทำให้ง่ายต่อการใช้งานตามธรรมชาติเช่น: myArray.smartSort('a'). หากคุณต้องการนำไปใช้กับเบราว์เซอร์รุ่นเก่าหรือคุณไม่ชอบการแก้ไขออบเจกต์ดั้งเดิมให้เลื่อนลงไปที่เวอร์ชันเมธอดเท่านั้น

/* 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 (Array, "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 คำตอบของคุณเหมือนกับคำตอบที่ยอมรับ คุณสามารถเพิ่มคำอธิบายใด ๆ ลงในคำตอบของคุณเพื่อบอกว่าทำไมจึงเป็นที่ต้องการมากกว่าคำตอบที่ยอมรับได้?
เพียงแค่ Ged

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:

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

0

ในขณะที่วิธีการเรียงลำดับแปลงองค์ประกอบ Array เป็นสตริง ดังนั้นวิธีด้านล่างก็ใช้งานได้ดีกับตัวเลขทศนิยมที่มีองค์ประกอบอาร์เรย์

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

นี่คือฟังก์ชั่นการเรียงลำดับของฉันในห้องสมุด 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
มันผิดธรรมดา! ฟังก์ชัน sort ต้องส่งคืนค่าลบ 0 หรือตัวเลขบวกไม่ใช่จริงหรือเท็จ
jperelli

ตามที่ @ jperelli ได้กล่าวถึงฟังก์ชั่นการจัดเรียงต้องการตัวเลขไม่ใช่บูลีนที่จะถูกส่งกลับ (และกำหนดว่าจะมี 3 สถานะที่เป็นไปได้เท่ากับด้านบนและด้านล่างนี้จำเป็นต้องมีการเรียงแบบเสถียร) ตามที่ระบุไว้คำตอบของคุณมันไม่ทำงาน a-bควรใช้แทน (คุณสามารถจินตนาการและทำสิ่งNumber(a>b)-0.5นั้นได้ แต่นั่นก็ยังไม่ใช่การจัดเรียงที่เสถียร)
ecc521
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.