เรียงลำดับวัตถุในอาร์เรย์ตามลำดับตัวอักษรบนคุณสมบัติหนึ่งของอาร์เรย์


201

สมมติว่าคุณมีคลาส JavaScript เช่นนี้

var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

สมมติว่าคุณสร้างอินสแตนซ์ของคลาสนั้นและเก็บไว้ในอาร์เรย์

var objArray = [];
objArray.push(DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

DepartmentFactoryดังนั้นตอนนี้ผมจะมีอาร์เรย์ของวัตถุที่สร้างขึ้นโดย ฉันจะใช้array.sort()วิธีการเรียงลำดับแถวลำดับของวัตถุนี้ด้วยDepartmentNameคุณสมบัติของแต่ละวัตถุได้อย่างไร

array.sort()วิธีการทำงานได้ดีเมื่อเรียงลำดับอาร์เรย์ของสตริง

var myarray=["Bob", "Bully", "Amy"];
myarray.sort(); //Array now becomes ["Amy", "Bob", "Bully"]

แต่ฉันจะทำให้มันทำงานกับรายการของวัตถุได้อย่างไร


คุณสามารถส่งผ่านฟังก์ชั่นการเรียงลำดับเป็นอาร์กิวเมนต์แรกถึง. เรียง ()
พอลทอมบลิ

2
เนื่องจากคุณใช้DepartmentFactoryเป็นตัวสร้างให้สร้างวัตถุโดยใช้new DepartmentFactoryมิฉะนั้นอาร์เรย์จะเต็มไปด้วยundefinedค่าจำนวนมาก
Anurag

คำตอบ:


342

คุณจะต้องทำสิ่งนี้:

objArray.sort(function(a, b) {
    var textA = a.DepartmentName.toUpperCase();
    var textB = b.DepartmentName.toUpperCase();
    return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});

หมายเหตุ: การเปลี่ยนเคส (เป็นสูงสุดหรือต่ำกว่า) ช่วยให้มั่นใจได้ว่าการเรียงลำดับตัวพิมพ์เล็กและใหญ่


3
ฉันมาหาคำตอบของคุณ 50 พันล้านครั้งเพราะฉันจำไม่ได้ว่าทำสิ่งนี้ได้อย่างไร FWIW, Linter ของฉันมักจะบอกผม "วงเล็บเปล่ารอบนิพจน์": return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;ไม่ gonna แก้ไขคำตอบของคุณถือเอาความหวังอย่างน้อยผมจะจำสิ่งที่ linting :)
ไมเคิล Tranchida

ขอบคุณสำหรับ Omer นี้
Ted Fitzpatrick

พบปัญหากับรหัสนี้ ใช้ตัวอักษรพิมพ์เล็กและตัวพิมพ์ใหญ่ผสมกัน อดีต credit_card_no และเมือง รหัสจะเรียงลำดับรายการ แต่คำที่ขึ้นต้นด้วย 'c' จะไม่ถูกจัดกลุ่มเข้าด้วยกัน
Kedar

156

เพื่อรองรับ Unicode:

objArray.sort(function(a, b) {
   return a.DepartmentName.localeCompare(b.DepartmentName);
});

7
สำหรับรุ่นที่ไม่ตรงตามตัวพิมพ์ใหญ่ให้ใช้บรรทัดต่อไปนี้ในบรรทัดที่ 2:return a.DepartmentName.toLowerCase().localeCompare(b.DepartmentName.toLowerCase());
Ben Barreth

3
เรียนรู้สิ่งใหม่ทุกวัน - localeCompareเจ๋งและสนับสนุนเบราว์เซอร์ทั้งหมดสำหรับ ARG แรก ไม่เลว!
obzenner

4
@BenBarreth ไม่มีเหตุผลใดที่จะใช้ตัวพิมพ์เล็กและตัวพิมพ์เล็ก จุดทั้งหมดของlocaleCompareคือการแบ่งการทำงานของการจัดการตรรกะการเรียงลำดับและสถานที่เกิดเหตุในระบบ หากการเรียงลำดับตัวพิมพ์เล็กและตัวพิมพ์เล็กเป็นเรื่องปกติสำหรับโลแคลเนื่องจากเป็นภาษาอังกฤษสิ่งนี้จะทำเพื่อคุณ: "Z" > 'a' // false "Z".localeCompare('a') // 1 หากคุณต้องการเบี่ยงเบนจากค่าเริ่มต้นของโลแคลคุณสามารถส่งแทนทับในพารามิเตอร์localesและoptions: developer.mozilla org / en-US / docs / เว็บ / JavaScript / ข้อมูลอ้างอิง / …
Jon z

12
var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

// use `new DepartmentFactory` as given below. `new` is imporatant

var objArray = [];
objArray.push(new DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(new DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(new DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(new DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

function sortOn(property){
    return function(a, b){
        if(a[property] < b[property]){
            return -1;
        }else if(a[property] > b[property]){
            return 1;
        }else{
            return 0;   
        }
    }
}

//objArray.sort(sortOn("id")); // because `this.id = data.Id;`
objArray.sort(sortOn("name")); // because `this.name = data.DepartmentName;`
console.log(objArray);

ตัวอย่าง: http://jsfiddle.net/diode/hdgeH/


9
// Sorts an array of objects "in place". (Meaning that the original array will be modified and nothing gets returned.)
function sortOn (arr, prop) {
    arr.sort (
        function (a, b) {
            if (a[prop] < b[prop]){
                return -1;
            } else if (a[prop] > b[prop]){
                return 1;
            } else {
                return 0;   
            }
        }
    );
}

//Usage example:

var cars = [
        {make:"AMC",        model:"Pacer",  year:1978},
        {make:"Koenigsegg", model:"CCGT",   year:2011},
        {make:"Pagani",     model:"Zonda",  year:2006},
        ];

// ------- make -------
sortOn(cars, "make");
console.log(cars);

/* OUTPUT:
AMC         : Pacer : 1978
Koenigsegg  : CCGT  : 2011
Pagani      : Zonda : 2006
*/



// ------- model -------
sortOn(cars, "model");
console.log(cars);

/* OUTPUT:
Koenigsegg  : CCGT  : 2011
AMC         : Pacer : 1978
Pagani      : Zonda : 2006
*/



// ------- year -------
sortOn(cars, "year");
console.log(cars);

/* OUTPUT:
AMC         : Pacer : 1978
Pagani      : Zonda : 2006
Koenigsegg  : CCGT  : 2011
*/

5

การสาธิต

var DepartmentFactory = function(data) {
    this.id = data.Id;
    this.name = data.DepartmentName;
    this.active = data.Active;
}

var objArray = [];
objArray.push(new DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(new DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(new DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(new DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));

console.log(objArray.sort(function(a, b) { return a.name > b.name}));


1

ทำเช่นนี้

objArrayy.sort(function(a, b){
 var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase()
 if (nameA < nameB) //sort string ascending
  return -1
 if (nameA > nameB)
  return 1
 return 0 //default return value (no sorting)
});
console.log(objArray)

1
objArray.sort( (a, b) => a.id.localeCompare(b.id, 'en', {'sensitivity': 'base'}));

นี่เป็นการเรียงลำดับตามตัวอักษรและไม่คำนึงถึงขนาดตัวพิมพ์ นอกจากนี้ยังสะอาดและอ่านง่าย: D


สวยงามกว่าโซลูชันที่ยอมรับ!
kano

0

นี่คือฟังก์ชั่นที่เรียบง่ายที่คุณสามารถใช้เพื่อเรียงลำดับอาร์เรย์ของวัตถุผ่านคุณสมบัติของพวกเขา; มันไม่สำคัญว่าคุณสมบัติจะเป็นประเภทของสตริงหรือจำนวนเต็มมันจะทำงานได้

    var cars = [
        {make:"AMC",        model:"Pacer",  year:1978},
        {make:"Koenigsegg", model:"CCGT",   year:2011},
        {make:"Pagani",     model:"Zonda",  year:2006},
    ];

    function sortObjectsByProp(objectsArr, prop, ascending = true) {
        let objectsHaveProp = objectsArr.every(object => object.hasOwnProperty(prop));
        if(objectsHaveProp)    {
            let newObjectsArr = objectsArr.slice();
            newObjectsArr.sort((a, b) => {
                if(isNaN(Number(a[prop])))  {
                    let textA = a[prop].toUpperCase(),
                        textB = b[prop].toUpperCase();
                    if(ascending)   {
                        return textA < textB ? -1 : textA > textB ? 1 : 0;
                    } else {
                        return textB < textA ? -1 : textB > textA ? 1 : 0;
                    }
                } else {
                    return ascending ? a[prop] - b[prop] : b[prop] - a[prop];
                }
            });
            return newObjectsArr;
        }
        return objectsArr;
    }

    let sortedByMake = sortObjectsByProp(cars, "make"); // returns ascending order by its make;
    let sortedByYear = sortObjectsByProp(cars, "year", false); // returns descending order by its year,since we put false as a third argument;
    console.log(sortedByMake);
    console.log(sortedByYear);


-1

คุณต้องผ่านฟังก์ชั่นที่ยอมรับพารามิเตอร์สองตัวเปรียบเทียบและส่งกลับตัวเลขดังนั้นสมมติว่าคุณต้องการเรียงลำดับตาม ID ที่คุณจะเขียน ...

objArray.sort(function(a,b) {
    return a.id-b.id;
});
// objArray is now sorted by Id

5
เขาถามเกี่ยวกับการเรียงลำดับตาม DepartmentName ไม่ใช่รหัส
พอลทอมบลิ

ฉันลองสิ่งนี้และดูเหมือนจะไม่ทำงานกับคอลัมน์สตริง ... มันทำงานบนคอลัมน์วันที่ สิ่งที่ได้ผลคือคำตอบจาก @ omer-bokhari
tsando

-2

หลังจากลองทำสิ่งนี้นิดหน่อยและพยายามทำลูปให้น้อยที่สุดฉันก็ลงเอยด้วยวิธีแก้ปัญหานี้:

การสาธิตเกี่ยวกับ codepen

const items = [
      {
        name: 'One'
      },
      {
        name: 'Maria is here'
      },
      {
        name: 'Another'
      },
      {
        name: 'Z with a z'
      },
      {
        name: '1 number'
      },
      {
        name: 'Two not a number'
      },
      {
        name: 'Third'
      },
      {
        name: 'Giant'
      }
    ];

    const sorted = items.sort((a, b) => {
      return a[name] > b[name];
    });

    let sortedAlphabetically = {};

    for(var item in sorted) {
      const firstLetter = sorted[item].name[0];
      if(sortedAlphabetically[firstLetter]) {
        sortedAlphabetically[firstLetter].push(sorted[item]);
      } else {
        sortedAlphabetically[firstLetter] = [sorted[item]]; 
      }
    }

    console.log('sorted', sortedAlphabetically);

-3

คำตอบง่ายๆ:

objArray.sort(function(obj1, obj2) {
   return obj1.DepartmentName > obj2.DepartmentName;
});

วิธี ES6:

objArray.sort((obj1, obj2) => {return obj1.DepartmentName > obj2.DepartmentName};

หากคุณต้องการทำให้มันเป็นตัวพิมพ์เล็ก / ตัวพิมพ์ใหญ่ให้ทำเช่นนั้นและเก็บผลลัพธ์นั้นไว้ในตัวแปรแทนที่จะเปรียบเทียบตัวแปรนั้น ตัวอย่าง:

objArray.sort((obj1, obj2) => {
   var firstObj = obj1.toLowerCase();
   var secondObj = obj2.toLowerCase();
   return firstObj.DepartmentName > secondObj.DepartmentName;
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.