Sắp xếp các đối tượng trong một mảng theo thứ tự abc trên một thuộc tính của mảng


201

Giả sử bạn có một lớp JavaScript như thế này

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

Giả sử bạn tạo một số thể hiện của lớp đó và lưu trữ chúng trong một mảng

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

Vì vậy, bây giờ tôi sẽ có một loạt các đối tượng được tạo bởi DepartmentFactory. Làm thế nào tôi có thể sử dụng array.sort()phương thức để sắp xếp mảng các đối tượng này theo thuộc DepartmentNametính của từng đối tượng?

Các array.sort()phương pháp làm việc tốt khi sắp xếp một mảng của chuỗi

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

Nhưng làm thế nào để tôi làm cho nó hoạt động với một danh sách các đối tượng?


Bạn có thể truyền một hàm sắp xếp làm đối số đầu tiên cho .sort ().
Paul Tomblin

2
Vì bạn đang sử dụng DepartmentFactorynhư một hàm tạo, hãy tạo các đối tượng của nó bằng cách sử dụng new DepartmentFactory, nếu không thì mảng sẽ chứa đầy một loạt các undefinedgiá trị.
Anurag

Câu trả lời:


342

bạn sẽ phải làm một cái gì đó như thế này:

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

lưu ý: thay đổi trường hợp (sang trên hoặc dưới) đảm bảo sắp xếp không phân biệt chữ hoa chữ thường.


3
Tôi đã đến câu trả lời của bạn 50 lần, vì tôi không bao giờ có thể nhớ cách làm điều này. FWIW, Linter tôi luôn thông báo cho tôi về "ngoặc vu vơ xung quanh khái niệm": return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;Không sẽ chỉnh sửa câu trả lời của bạn, giữ ra hy vọng tôi ít nhất sẽ nhớ điều Linting :)
Michael Tranchida

Cảm ơn vì Omer này
Ted Fitzpatrick

Tìm thấy một vấn đề với mã này. Sử dụng kết hợp các chữ cái thấp hơn và viết hoa. Ví dụ. credit_card_no và Thành phố. Mã này sắp xếp danh sách nhưng các từ bắt đầu bằng 'c' không được nhóm lại với nhau.
Kedar

157

Để hỗ trợ unicode:

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

7
Đối với phiên bản không phân biệt chữ hoa chữ thường, hãy sử dụng dòng sau trên dòng 2:return a.DepartmentName.toLowerCase().localeCompare(b.DepartmentName.toLowerCase());
Ben Barreth

3
học một cái gì đó mới mỗi ngày - localeComparethật tuyệt và có tất cả sự hỗ trợ của trình duyệt cho đối số đầu tiên. Không tệ!
obzenner

4
@BenBarreth không có lý do để viết thường các chuỗi. toàn bộ vấn đề localeComparelà để hoàn thành công việc quản lý logic sắp xếp và các quirks cục bộ cho hệ thống. Nếu việc sắp xếp không phân biệt chữ hoa chữ thường là bình thường đối với miền địa phương, như trong tiếng Anh, thì điều này sẽ được thực hiện cho bạn: "Z" > 'a' // false "Z".localeCompare('a') // 1 Nếu bạn muốn đi chệch khỏi mặc định của miền địa phương, bạn có thể gửi các ghi đè trong localesoptionstham số: developer.mozilla. org / en-US / docs / Web / JavaScript / Reference /
Mạnh

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

bản demo: 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

BẢN GIỚI THIỆU

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

2
objArray.sort((a, b) => a.DepartmentName.localeCompare(b.DepartmentName))

1

làm như thế này

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

Điều này sắp xếp chúng theo bảng chữ cái VÀ không phân biệt chữ hoa chữ thường. Nó cũng siêu sạch và dễ đọc: D


Thanh lịch hơn nhiều so với giải pháp được chấp nhận!
kano

0

Đây là một hàm đơn giản mà bạn có thể sử dụng để sắp xếp mảng các đối tượng thông qua các thuộc tính của chúng; không quan trọng nếu thuộc tính là một loại chuỗi hoặc số nguyên, nó sẽ hoạt động.

    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

Bạn phải truyền một hàm chấp nhận hai tham số, so sánh chúng và trả về một số, vì vậy giả sử bạn muốn sắp xếp chúng theo ID bạn sẽ viết ...

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

5
Anh ấy hỏi về việc sắp xếp theo DepartmentName, không phải Id.
Paul Tomblin

Tôi đã thử cái này và cái này dường như không hoạt động trên các cột chuỗi ... nó hoạt động trên cột ngày. Những gì đã làm việc là giải pháp từ @ omer-bokhari
tsando

-2

Sau khi thử một chút về điều này và cố gắng tạo ra ít vòng lặp nhất có thể, tôi đã kết thúc với giải pháp này:

Bản demo trên 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

Một câu trả lời đơn giản:

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

Cách ES6:

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

Nếu bạn cần làm cho chữ thường / chữ hoa, v.v., chỉ cần làm điều đó và lưu trữ kết quả đó trong một biến hơn so với biến đó. Thí dụ:

objArray.sort((obj1, obj2) => {
   var firstObj = obj1.toLowerCase();
   var secondObj = obj2.toLowerCase();
   return firstObj.DepartmentName > secondObj.DepartmentName;
});
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.