Sắp xếp thuộc tính đối tượng theo các giá trị


696

Nếu tôi có một đối tượng JavaScript như:

var list = {
  "you": 100, 
  "me": 75, 
  "foo": 116, 
  "bar": 15
};

Có cách nào để sắp xếp các thuộc tính dựa trên giá trị? Vì vậy, tôi kết thúc với

list = {
  "bar": 15, 
  "me": 75, 
  "you": 100, 
  "foo": 116
};

4
Không chỉ "sắp xếp", mà quan trọng hơn là sắp xếp các số. Các số miễn dịch với phương thức Javascripts Array.sort (), có nghĩa là bạn sẽ không chỉ phải tìm một phương pháp để sắp xếp các thuộc tính, mà bạn sẽ phải viết hàm riêng của mình để so sánh các giá trị số.
Sampson

106
Trước khi bạn đọc câu trả lời: Câu trả lời là Không . Thứ tự của các thuộc tính đối tượng là không chuẩn trong ECMAScript. Bạn không bao giờ nên đưa ra các giả định về thứ tự các phần tử trong một đối tượng JavaScript. Một đối tượng là một tập hợp các thuộc tính không có thứ tự. Các câu trả lời dưới đây cho bạn thấy cách "sử dụng" các thuộc tính được sắp xếp, sử dụng sự trợ giúp của các mảng, nhưng thực sự không bao giờ thay đổi thứ tự các thuộc tính của chính các đối tượng. Vì vậy, không, nó không thể. Ngay cả khi bạn xây dựng một đối tượng với các thuộc tính được định sẵn, không đảm bảo rằng chúng sẽ hiển thị theo cùng một thứ tự trong tương lai. Đọc tiếp :).
Govind Rai

3
@GovindRai chưa, trong các ứng dụng lối vào thế giới thực, chúng tôi lặp qua các bộ sưu tập đối tượng với ID làm khóa và thứ tự rất quan trọng nếu được dịch sang các mẫu HTML. Bạn nói rằng họ không có thứ tự, tôi nói họ có chính xác thứ tự mà tôi thấy khi console. Đưa họ vào trình duyệt hiện tại. Và thứ tự đó có thể được sắp xếp lại. Ngay sau khi bạn lặp lại chúng, họ có một đơn đặt hàng.
Vấn

7
@GovindRai: Hiện tại có một phương tiện truy cập các thuộc tính theo thứ tự được chỉ định trong thông số kỹ thuật. Nó là một ý tưởng tốt? Hầu như chắc chắn là không. :-) Nhưng nó ở đó, kể từ ES2015.
TJ Crowder

7
Khách truy cập năm 2019: kiểm tra Object.entriescâu trả lời dựa trên hầu như không được nêu lên này là trạng thái sạch nhất và dễ đọc nhất của nghệ thuật kể từ ES2017: stackoverflow.com/a/37607084/245966
jakub.g

Câu trả lời:


705

Di chuyển chúng đến một mảng, sắp xếp mảng đó và sau đó sử dụng mảng đó cho mục đích của bạn. Đây là một giải pháp:

var maxSpeed = {
    car: 300, 
    bike: 60, 
    motorbike: 200, 
    airplane: 1000,
    helicopter: 400, 
    rocket: 8 * 60 * 60
};
var sortable = [];
for (var vehicle in maxSpeed) {
    sortable.push([vehicle, maxSpeed[vehicle]]);
}

sortable.sort(function(a, b) {
    return a[1] - b[1];
});

//[["bike", 60], ["motorbike", 200], ["car", 300],
//["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]

Khi bạn có mảng, bạn có thể xây dựng lại đối tượng từ mảng theo thứ tự bạn thích, do đó đạt được chính xác những gì bạn đặt ra. Điều đó sẽ hoạt động trong tất cả các trình duyệt mà tôi biết, nhưng nó sẽ phụ thuộc vào một vấn đề khó thực hiện và có thể bị hỏng bất cứ lúc nào. Bạn không bao giờ nên đưa ra các giả định về thứ tự các phần tử trong một đối tượng JavaScript.

var objSorted = {}
sortable.forEach(function(item){
    objSorted[item[0]]=item[1]
})

24
Bạn có thể vui lòng định dạng lại "bạn có thể xây dựng lại" thành "bạn có thể sử dụng mảng để duy trì thứ tự các khóa và kéo các giá trị từ đối tượng" không? Không chỉ là không chuẩn, như bạn đã đề cập, giả định sai lầm này bị phá vỡ bởi nhiều trình duyệt hơn là Chrome ngày nay, vì vậy tốt hơn hết là không khuyến khích người dùng dùng thử.
Oleg V. Volkov

32
Đây là một phiên bản nhỏ gọn hơn của mã của bạn. Object.keys (maxSpeed) .sort (hàm (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain

6
@TheBrain: Chỉ cần thêm, keys()chỉ được hỗ trợ bởi IE9 + (và các trình duyệt hiện đại khác), nếu đó là điều đáng quan tâm. Cũng keys()loại trừ các thuộc tính vô số khỏi chuỗi nguyên mẫu (không giống như for..in) - nhưng điều đó thường được mong muốn hơn.
MrWhite

31
_.pairsbiến một đối tượng thành [[key1, value1], [key2, value2]]. Sau đó gọi sắp xếp trên đó. Sau đó gọi _.objectnó để biến nó trở lại.
Funkodebat

2
Dự án của tôi yêu cầu các khóa đối tượng để hợp nhất sạch sẽ, nhưng cũng yêu cầu sắp xếp rõ ràng là giao diện người dùng siêu dữ liệu. Tôi đã làm theo một cách tiếp cận tương tự chỉ tôi đã thêm một kiểm tra hasOwnProperty để tránh thu thập dữ liệu chuỗi nguyên mẫu. Đây là một bài viết hay về việc lặp lại các thuộc tính của đối tượng trong JS hackernoon.com/
Kẻ

416

Chúng tôi không muốn sao chép toàn bộ cấu trúc dữ liệu hoặc sử dụng một mảng mà chúng tôi cần một mảng kết hợp.

Đây là một cách khác để làm điều tương tự như bonna:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted);     // bar,me,you,foo


22
Điều này dường như được sắp xếp theo khóa, không phải giá trị, đó không phải là câu hỏi được gọi là gì?
Michael

27
Nó được sắp xếp theo giá trị và hiển thị các khóa - nhưng chúng tôi mất số lượng giá trị khi in ra, vì nó chỉ in các khóa.
Hanna

6
Thứ tự thuộc tính đối tượng không được đảm bảo trong JavaScript, vì vậy việc sắp xếp nên được thực hiện thành một mảng, không phải là một đối tượng (đó là những gì bạn đang đề cập đến như là một 'mảng kết hợp').
Christopher Meyers

6
Đừng quên. keysSortedlà một mảng! Không phải là một đối tượng!
Màu xanh lá cây

17
Nếu bạn thêm .map(key => list[key]);vào cuối của loại, nó sẽ trả về toàn bộ đối tượng thay vì chỉ là chìa khóa
James Moran

182

Các đối tượng của bạn có thể có bất kỳ số lượng thuộc tính nào và bạn có thể chọn sắp xếp theo bất kỳ thuộc tính đối tượng nào bạn muốn, số hoặc chuỗi, nếu bạn đặt các đối tượng trong một mảng. Hãy xem xét mảng này:

var arrayOfObjects = [   
    {
        name: 'Diana',
        born: 1373925600000, // Mon, Jul 15 2013
        num: 4,
        sex: 'female'
    },
    {

        name: 'Beyonce',
        born: 1366832953000, // Wed, Apr 24 2013
        num: 2,
        sex: 'female'
    },
    {            
        name: 'Albert',
        born: 1370288700000, // Mon, Jun 3 2013
        num: 3,
        sex: 'male'
    },    
    {
        name: 'Doris',
        born: 1354412087000, // Sat, Dec 1 2012
        num: 1,
        sex: 'female'
    }
];

sắp xếp theo ngày sinh, cũ nhất

// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
    return a.born - b.born;
});
console.log('by date:');
console.log(byDate);

sắp xếp theo tên

var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
    var x = a.name.toLowerCase();
    var y = b.name.toLowerCase();
    return x < y ? -1 : x > y ? 1 : 0;
});

console.log('by name:');
console.log(byName);

http://jsfiddle.net/xsM5s/16/


1
Sắp xếp theo tên không nên substrra ký tự đầu tiên; khác DianaDebracó một thứ tự không xác định. Ngoài ra, byDateloại của bạn thực sự sử dụng num, không born.
Lawrence Dol

Điều này có vẻ tốt, nhưng lưu ý rằng để so sánh các chuỗi bạn chỉ có thể sử dụngx.localeCompare(y)
Jemar Jones

2
@JemarJones localComparetrông giống như một chức năng rất hữu ích! Chỉ cần lưu ý rằng nó sẽ không được hỗ trợ trong mọi trình duyệt - IE 10 trở xuống, Safari Mobile 9 trở xuống.
inorganik

@inorganik Có lưu ý rất tốt cho những người cần hỗ trợ những trình duyệt
Jemar Jones

1
Đây là một mảng các Đối tượng, không phải là OP yêu cầu (một Đối tượng có nhiều thuộc tính)
João Pimentel Ferreira

62

Để hoàn thiện, hàm này trả về mảng các thuộc tính đối tượng được sắp xếp :

function sortObject(obj) {
    var arr = [];
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            arr.push({
                'key': prop,
                'value': obj[prop]
            });
        }
    }
    arr.sort(function(a, b) { return a.value - b.value; });
    //arr.sort(function(a, b) { a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
    return arr; // returns array
}

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]

Jsfiddle với mã ở trên là ở đây . Giải pháp này dựa trên bài viết này .

Fiddle cập nhật để sắp xếp các chuỗi ở đây. Bạn có thể xóa cả chuyển đổi .toLowerCase () bổ sung khỏi nó để so sánh chuỗi phân biệt chữ hoa chữ thường.


1
Còn một mảng đối tượng thì sao? [{name: Will}, {name: Bill}, {name: Ben}]
Will Hancock

1
Xin chào, bạn có thể sử dụng chức năng localeCompare để so sánh này. Đã thêm nó vào câu trả lời ở trên.
Stano

Giải pháp tuyệt vời. Sắp xếp chuỗi cần trả về
pfwd

@Stano Giải pháp đúng và đơn giản. Cám ơn rất nhiều.
Abrar Hossain

48

ECMAScript 2017 giới thiệu Object.values / Object.entries. Như tên cho thấy, cái trước tổng hợp tất cả các giá trị của một đối tượng thành một mảng, và cái sau thực hiện toàn bộ đối tượng thành một mảng các [key, value]mảng; Python tương đương dict.values()dict.items().

Các tính năng giúp dễ dàng sắp xếp bất kỳ hàm băm nào vào một đối tượng được sắp xếp. Đến bây giờ, chỉ một phần nhỏ nền tảng JavaScript hỗ trợ chúng , nhưng bạn có thể dùng thử trên Firefox 47+.

let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};

let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]

let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]

Làm thế nào điều này có thể trả lời tiêu đề của câu hỏi Sorting JavaScript Object by property value? bạn đã hiểu nhầm câu hỏi tôi nghĩ, vì bạn phải thay đổi Object ban đầu và không tạo ra một Array mới từ nó.
vsync

2
@vsync Câu trả lời này cho kết quả giống như câu trả lời được chấp nhận, nhưng với ít mã hơn và không có biến tạm thời.
Darren Cook

3
FWIW, câu trả lời này là sạch af và là người duy nhất đã giúp tôi.
NetOperator Wibby

Chỉ trong ff, không có nghĩa là chrome cũng không tự động sắp xếp các đối tượng. wtf
fb

Chỉ cần lưu ý rằng điều này sẽ không bảo tồn các khóa.
Vael Victus

40

Phiên bản "mũi tên" của câu trả lời của @marcusR để tham khảo

var myObj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(myObj).sort((a,b) => myObj[a]-myObj[b])
alert(keysSorted);     // bar,me,you,foo

CẬP NHẬT: Tháng 4 năm 2017 - Điều này trả về một myObjđối tượng được sắp xếp được xác định ở trên.

Object
 .keys(myObj)
 .sort((a, b) => myObj[a]-myObj[b])
 .reduce((_sortedObj, key) => ({
   ..._sortedObj, 
   [key]: myObj[key]
 }), {})

Hãy thử nó ở đây!

CẬP NHẬT: Tháng 10 năm 2018 - Phiên bản Object.entries

Object
 .entries(myObj)
 .sort()
 .reduce((_sortedObj, [k,v]) => ({
   ..._sortedObj, 
   [k]: v
 }), {})

Hãy thử nó ở đây!


1
không hoạt động chovar myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
Rohanil

5
Câu hỏi của OP, cùng với câu trả lời này không chứa các đối tượng lồng nhau @Rohanil Có lẽ bạn muốn hỏi một câu hỏi khác thay vì bỏ phiếu xuống. Đối tượng lồng nhau của bạn với nhiều loại khác nhau rõ ràng cần nhiều hơn giải pháp này cung cấp
Jason J. Nathan

Chỉ cần một lưu ý: cập nhật của bạn sẽ không thực sự hoạt động. Ít nhất là không phải ở khắp mọi nơi và không phải vì entries. Theo tiêu chuẩn, một đối tượng là một tập hợp các thuộc tính không có thứ tự . Chà, điều đó có nghĩa là nếu bạn đang cố gắng xây dựng đối tượng mới sau khi sắp xếp nó theo giá trị thuộc tính hoặc bất cứ thứ gì khác, thứ tự khóa thuộc tính sẽ không được xác định lại. Chrome, ví dụ, theo mặc định, sắp xếp các khóa thuộc tính, do đó mọi nỗ lực để đặt hàng chúng khác nhau là vô ích. Cơ hội duy nhất của bạn là có được một "chỉ mục" dựa trên sở thích đặt hàng của bạn và duyệt qua đối tượng ban đầu tương ứng.
ZorgoZ

Có @ZorgoZ, bạn đã đúng và nhiều người đã đề cập đến nó trên bài đăng này. Hầu hết thời gian, chúng tôi sử dụng hàm này như một phép chuyển đổi trước khi chuyển đổi sang loại khác (như JSON) hoặc trước hàm giảm khác. Nếu mục tiêu là làm biến đổi đối tượng sau đó, thì có thể có kết quả bất ngờ. Tôi đã thành công với chức năng này trên các động cơ.
Jason J. Nathan

Lưu ý: bạn không muốn sử dụng sort()trênObject.entries()
Solvitieg

36

Các đối tượng JavaScript không được sắp xếp theo định nghĩa (xem Đặc tả ngôn ngữ ECMAScript , phần 8.6). Đặc tả ngôn ngữ thậm chí không đảm bảo rằng, nếu bạn lặp lại các thuộc tính của một đối tượng hai lần liên tiếp, chúng sẽ xuất hiện theo thứ tự lần thứ hai.

Nếu bạn cần thứ tự để đặt hàng, hãy sử dụng một mảng và phương thức Array.prototype.sort.


4
Lưu ý rằng đã có khá nhiều tranh cãi về điều này. Hầu hết các triển khai giữ danh sách theo thứ tự các yếu tố đã được thêm vào. IIRC, Chrome thì không. Đã có tranh luận về việc liệu Chrome có phù hợp với các triển khai khác hay không. Tôi tin rằng một đối tượng JavaScript là hàm băm và không nên đặt hàng. Tôi tin rằng Python đã trải qua cùng một lập luận và một danh sách giống như hàm băm mới được đặt hàng gần đây đã được giới thiệu. Đối với hầu hết các trình duyệt, bạn CÓ THỂ làm những gì bạn muốn bằng cách tạo lại đối tượng của bạn, thêm các yếu tố theo giá trị được sắp xếp. Nhưng bạn không nên.
Nosredna

Biên tập. Chrome thường giữ trật tự, nhưng không phải lúc nào cũng vậy. Và đây là lỗi Chromium có liên quan: code.google.com/p/chromium/issues/detail?id=883
Nosredna

6
Báo cáo lỗi đó là không chính đáng, và những người dựa vào hành vi không có giấy tờ là những người có lỗi. Đọc phần ECMASCript 8.6; nó nói rõ rằng "Một đối tượng là một tập hợp các thuộc tính không có thứ tự". Bất cứ ai phát hiện ra rằng nó không có vẻ như vậy trong một vài lần triển khai, và sau đó bắt đầu phụ thuộc vào hành vi cụ thể của việc triển khai đó, đã phạm một sai lầm lớn và họ không nên cố gắng gạt bỏ sự đổ lỗi khỏi chính mình. Nếu tôi ở trong nhóm Chrome, tôi sẽ đánh dấu báo cáo lỗi đó là "Không hợp lệ, WontFix".
NickFitz

8
EcmaScript 5 thực sự định nghĩa thứ tự liệt kê là thứ tự chèn - sự vắng mặt của định nghĩa được coi là một lỗi đặc tả trong ES3. Điều đáng chú ý là thông số EcmaScript xác định hành vi mà không ai sẽ xem xét lành mạnh - ví dụ hành vi thông số kỹ thuật là lỗi cú pháp trong nhiều trường hợp bị ném khi chạy, sử dụng không đúng cách tiếp tục, ngắt, ++, -, const, v.v. với thông số kỹ thuật, bất kỳ động cơ nào ném ngoại lệ trước khi tiếp cận mã đó là sai
olliej

4
@olliej - Tôi không nghĩ điều này là chính xác. Thông số kỹ thuật cho biết: "Cơ chế và thứ tự liệt kê các thuộc tính (bước 6.a trong thuật toán đầu tiên, bước 7.a trong lần thứ hai) không được chỉ định". Đây là trên trang 92 của bản PDF của bản thảo cuối cùng.
whitneyland

25

OK , như bạn có thể biết, javascript có hàm sort () , để sắp xếp các mảng, nhưng không có gì cho đối tượng ...

Vì vậy, trong trường hợp đó, bằng cách nào đó chúng ta cần lấy mảng các phím và sắp xếp chúng, đó là lý do apis cung cấp cho bạn các đối tượng trong một mảng hầu hết thời gian, bởi vì Array có nhiều chức năng riêng để chơi với chúng hơn là đối tượng theo nghĩa đen, dù sao, giải pháp nhanh đang sử dụng Object.key trả về một mảng các khóa đối tượng, tôi tạo hàm ES6 bên dưới để thực hiện công việc cho bạn, nó sử dụng các hàm sort ()less () trong javascript:

function sortObject(obj) {
  return Object.keys(obj)
    .sort().reduce((a, v) => {
    a[v] = obj[v];
    return a; }, {});
}

Và bây giờ bạn có thể sử dụng nó như thế này:

let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);

Kiểm tra sortMyObject và bạn có thể thấy kết quả được sắp xếp theo các khóa như thế này:

{a: 1, b: 2, c: 3, d: 4, e: 5}

Cũng theo cách này, đối tượng chính sẽ không được chạm vào và chúng tôi thực sự có được một đối tượng mới.

Tôi cũng tạo hình ảnh bên dưới, để làm cho các bước chức năng rõ ràng hơn, trong trường hợp bạn cần thay đổi nó một chút để làm việc theo cách của bạn:

Sắp xếp một đối tượng javascript theo giá trị thuộc tính


4
Điều này sắp xếp theo khóa, không phải theo giá trị.
ROROROOROROR

@ROROROOROROR, đó chỉ là một dấu hiệu cho thấy nó hoạt động như thế nào vì chúng không khác nhau, nhưng tất cả đều tốt, tôi cũng sẽ thêm sắp xếp theo giá trị
Alireza

1
Sắp xếp theo giá trị là sai và đó là tập dữ liệu của bạn. Thay đổi c: 3để c: 13và bạn sẽ thấy nó sụp đổ.
VtoCorleone

1
@VtoCorleone Đó chỉ là một lỗi sắp xếp tự nhiên, 1 xuất hiện trước, không phải là một lỗ hổng trong thuật toán như đã trình bày.
Michael Ryan Soileau

10
var list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
};

function sortAssocObject(list) {
    var sortable = [];
    for (var key in list) {
        sortable.push([key, list[key]]);
    }
    // [["you",100],["me",75],["foo",116],["bar",15]]

    sortable.sort(function(a, b) {
        return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
    });
    // [["bar",15],["me",75],["you",100],["foo",116]]

    var orderedList = {};
    for (var idx in sortable) {
        orderedList[sortable[idx][0]] = sortable[idx][1];
    }

    return orderedList;
}

sortAssocObject(list);

// {bar: 15, me: 75, you: 100, foo: 116}

Đơn giản và hoàn hảo! Điều này trả lời câu hỏi. Cảm ơn.
Ajay Singh

Thứ tự khóa không được đảm bảo trong javascript nên điều này không thành công đối với tôi nếu khóa là số nguyên hoặc tương tự
ParoX

chính xác, ParoX. Điều này không hoạt động chính xác khi khóa là loại số nguyên.
jungwon jin

8

Cập nhật với ES6: Nếu mối quan tâm của bạn là có một đối tượng được sắp xếp để lặp qua (đó là lý do tại sao tôi tưởng tượng bạn muốn các thuộc tính đối tượng của bạn được sắp xếp), bạn có thể sử dụng đối tượng Map .

Bạn có thể chèn các cặp (khóa, giá trị) của mình theo thứ tự được sắp xếp và sau đó thực hiện một for..ofvòng lặp sẽ đảm bảo có các vòng lặp theo thứ tự bạn đã chèn chúng

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// 0 = zero 
// 1 = one

Cũng trong ES6 (ES2015): thuộc tính đối tượng làm có trật tự (hoặc có một phương tiện để truy cập vào chúng theo một thứ tự xác định, tùy thuộc vào quan điểm của bạn). Nếu tên thuộc tính là chuỗi và không giống như chỉ mục mảng, thứ tự là thứ tự chúng được thêm vào đối tượng. Thứ tự này không được chỉ định để được tôn trọng bởi for-inhoặc Object.keys, nhưng nó được xác định là được tôn trọng bởi Object.getOwnPropertyNamesvà các phương thức mới khác để truy cập mảng tên thuộc tính. Vì vậy, đó là một lựa chọn khác.
TJ Crowder

Nhưng hoạt động của 'sort' ở đâu? Chúng hoàn toàn không được sắp xếp
Green

@Green Tôi nghĩ điều tôi muốn làm nổi bật ở đây là, với Mapbạn thực sự có một cấu trúc dữ liệu có thể lưu trữ theo thứ tự được sắp xếp (sắp xếp dữ liệu của bạn, lặp qua nó và lưu trữ nó trên bản đồ) khi bạn không đảm bảo rằng các đối tượng.
julianljk

6

Underscore.js hoặc Lodash.js để sắp xếp mảng hoặc đối tượng nâng cao

 var data={
        "models": {

            "LTI": [
                "TX"
            ],
            "Carado": [
                "A",
                "T",
                "A(пасс)",
                "A(груз)",
                "T(пасс)",
                "T(груз)",
                "A",
                "T"
            ],
            "SPARK": [
                "SP110C 2",
                "sp150r 18"
            ],
            "Autobianchi": [
                "A112"
            ]
        }
    };

    var arr=[],
        obj={};
    for(var i in data.models){
      arr.push([i, _.sortBy(data.models[i],function (el){return el;})]);
    }
    arr=_.sortBy(arr,function (el){
      return el[0];
    });
    _.map(arr,function (el){return obj[el[0]]=el[1];});
     console.log(obj);

bản giới thiệu


6

Rất ngắn gọn và đơn giản!

var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
    sortedList[key] = list[key]; });

5

Tôi đang theo giải pháp được đưa ra bởi slebetman (hãy đọc nó để biết tất cả các chi tiết), nhưng đã được điều chỉnh, vì đối tượng của bạn không được lồng nhau.

// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
    sort_array.push({key:key,value:list[key]});
}

// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});

// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
    var item = list[sort_array[i].key];

    // now do stuff with each item
}

4

Sắp xếp các giá trị không có nhiều vòng lặp (để sắp xếp theo các phím thay đổi chỉ mục trong cuộc gọi lại sắp xếp thành "0")

const list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
  };

let sorted = Object.fromEntries(
                Object.entries(list).sort( (a,b) => a[1] - b[1] )    
             ) 
console.log('Sorted object: ', sorted) 


2

Đây có thể là một cách đơn giản để xử lý nó như một đối tượng được đặt hàng thực sự. Không chắc nó chậm như thế nào. cũng có thể tốt hơn với một vòng lặp while.

Object.sortByKeys = function(myObj){
  var keys = Object.keys(myObj)
  keys.sort()
  var sortedObject = Object()
  for(i in keys){
    key = keys[i]
    sortedObject[key]=myObj[key]
   }

  return sortedObject

}

Và sau đó tôi tìm thấy hàm đảo ngược này từ: http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/

Object.invert = function (obj) {

  var new_obj = {};

  for (var prop in obj) {
    if(obj.hasOwnProperty(prop)) {
      new_obj[obj[prop]] = prop;
    }
  }

  return new_obj;
};

Vì thế

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)

2
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
  .sort((c,b) => {
    return a[b]-a[c]
  })
  .reduce((acc, cur) => {
    let o = {}
    o[cur] = a[cur]
    acc.push(o)
    return acc
   } , [])

đầu ra = [{p: 8}, {c: 2}, {b: 1}, {g: 1}]


2

Chỉ trong trường hợp, ai đó đang tìm cách giữ đối tượng (có khóa và giá trị), sử dụng tham chiếu mã bởi @Markus R và @James Moran bình luận, chỉ cần sử dụng:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
                 .map(key => newO[key] = list[key]);
console.log(newO);  // {bar: 15, me: 75, you: 100, foo: 116}

2
Bạn đang trả lại một nhiệm vụ trong đó map, forEachsẽ tốt hơn
DiegoRBaquero

2
let toSort = {a:2323, b: 14, c: 799} 
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1]) 

Đầu ra:

[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]

1

nhiều chức năng tương tự và hữu ích: https://github.com/shimondoodkin/groupbyfifts/

function sortobj(obj)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}

function sortobjkey(obj,key)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        k=key;      if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}

1

Đối tượng được sắp xếp theo giá trị (DESC)

function sortObject(list) {
  var sortable = [];
  for (var key in list) {
    sortable.push([key, list[key]]);
  }

  sortable.sort(function(a, b) {
    return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
  });

  var orderedList = {};
  for (var i = 0; i < sortable.length; i++) {
    orderedList[sortable[i][0]] = sortable[i][1];
  }

  return orderedList;
}

1

Đây là một ví dụ nữa:

function sortObject(obj) {
  var arr = [];
  var prop;
  for (prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      arr.push({
        'key': prop,
        'value': obj[prop]
      });
    }
  }
  arr.sort(function(a, b) {
    return a.value - b.value;
  });
  return arr; // returns array
}
var list = {
  car: 300,
  bike: 60,
  motorbike: 200,
  airplane: 1000,
  helicopter: 400,
  rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);


1
    var list = {
    "you": 100,
    "me": 75,
    "foo": 116,
    "bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
    var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
    tmpList[key] = list[key];
    delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }

1

TypeScript

Hàm sau sắp xếp đối tượng theo giá trị hoặc thuộc tính của giá trị. Nếu bạn không sử dụng TypeScript, bạn có thể xóa thông tin loại để chuyển đổi nó thành JavaScript.

/**
 * Represents an associative array of a same type.
 */
interface Dictionary<T> {
  [key: string]: T;
}

/**
 * Sorts an object (dictionary) by value or property of value and returns
 * the sorted result as a Map object to preserve the sort order.
 */
function sort<TValue>(
  obj: Dictionary<TValue>,
  valSelector: (val: TValue) => number | string,
) {
  const sortedEntries = Object.entries(obj)
    .sort((a, b) =>
      valSelector(a[1]) > valSelector(b[1]) ? 1 :
      valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
  return new Map(sortedEntries);
}

Sử dụng

var list = {
  "one": { height: 100, weight: 15 },
  "two": { height: 75, weight: 12 },
  "three": { height: 116, weight: 9 },
  "four": { height: 15, weight: 10 },
};

var sortedMap = sort(list, val => val.height);

Thứ tự các khóa trong một đối tượng JavaScript không được đảm bảo, vì vậy tôi sắp xếp và trả về kết quả dưới dạng một Mapđối tượng duy trì thứ tự sắp xếp.

Nếu bạn muốn chuyển đổi nó trở lại Object, bạn có thể làm điều này:

var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });

1

đầu vào là đối tượng, đầu ra là đối tượng, sử dụng lib lodash & js tích hợp, với tùy chọn giảm dần hoặc tăng dần và không làm thay đổi đối tượng đầu vào

ví dụ đầu vào và đầu ra

{
  "a": 1,
  "b": 4,
  "c": 0,
  "d": 2
}
{
  "b": 4,
  "d": 2,
  "a": 1,
  "c": 0
}

Việc thực hiện

const _ = require('lodash');

const o = { a: 1, b: 4, c: 0, d: 2 };


function sortByValue(object, descending = true) {
  const { max, min } = Math;
  const selector = descending ? max : min;

  const objects = [];
  const cloned = _.clone(object);

  while (!_.isEmpty(cloned)) {
    const selectedValue = selector(...Object.values(cloned));
    const [key, value] = Object.entries(cloned).find(([, value]) => value === selectedValue);

    objects.push({ [key]: value });
    delete cloned[key];
  }

  return _.merge(...objects);
}

const o2 = sortByValue(o);
console.log(JSON.stringify(o2, null, 2));

1
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]

const order = ['test2', 'test']

const setOrder = (arrayOfObjects, order) =>
    arrayOfObjects.sort((a, b) => {
        if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
            return -1;
        }

        if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
            return 1;
        }

        return 0;
    });

1

giải pháp của tôi với sắp xếp:

let list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
};

let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);

for(let element of sorted) {
    console.log(element[0]+ ": " + element[1]);
}

Vui lòng định dạng mã của bạn dưới dạng mã
Itamar Mushkin

1
<pre>
function sortObjectByVal(obj){  
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
    newObj[x] = obj[x];
}
return newObj;

}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>

1
Chào mừng đến với stackoverflow. Ngoài câu trả lời bạn đã cung cấp, vui lòng xem xét việc cung cấp giải thích ngắn gọn về lý do và cách khắc phục sự cố này.
jtate

0

Một cách khác để giải quyết điều này: -

var res = [{"s1":5},{"s2":3},{"s3":8}].sort(function(obj1,obj2){ 
 var prop1;
 var prop2;
 for(prop in obj1) {
  prop1=prop;
 }
 for(prop in obj2) {
  prop2=prop;
 }
 //the above two for loops will iterate only once because we use it to find the key
 return obj1[prop1]-obj2[prop2];
});

// res sẽ có mảng kết quả


0

Cảm ơn bạn và tiếp tục trả lời @Nosredna

Bây giờ chúng ta hiểu đối tượng cần phải được chuyển đổi thành mảng sau đó sắp xếp mảng. điều này rất hữu ích để sắp xếp mảng (hoặc đối tượng được chuyển đổi thành mảng) theo chuỗi:

Object {6: Object, 7: Object, 8: Object, 9: Object, 10: Object, 11: Object, 12: Object}
   6: Object
   id: "6"
   name: "PhD"
   obe_service_type_id: "2"
   __proto__: Object
   7: Object
   id: "7"
   name: "BVC (BPTC)"
   obe_service_type_id: "2"
   __proto__: Object


    //Sort options
    var sortable = [];
    for (var vehicle in options)
    sortable.push([vehicle, options[vehicle]]);
    sortable.sort(function(a, b) {
        return a[1].name < b[1].name ? -1 : 1;
    });


    //sortable => prints  
[Array[2], Array[2], Array[2], Array[2], Array[2], Array[2], Array[2]]
    0: Array[2]
    0: "11"
    1: Object
        id: "11"
        name: "AS/A2"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2
        __proto__: Array[0]
    1: Array[2]
    0: "7"
    1: Object
        id: "7"
        name: "BVC (BPTC)"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2

0

Thử cái này. Ngay cả đối tượng của bạn không có tài sản dựa trên đó bạn đang cố gắng sắp xếp cũng sẽ bị xử lý.

Chỉ cần gọi nó bằng cách gửi tài sản với đối tượng.

var sortObjectByProperty = function(property,object){

    console.time("Sorting");
    var  sortedList      = [];
         emptyProperty   = [];
         tempObject      = [];
         nullProperty    = [];
    $.each(object,function(index,entry){
        if(entry.hasOwnProperty(property)){
            var propertyValue = entry[property];
            if(propertyValue!="" && propertyValue!=null){
              sortedList.push({key:propertyValue.toLowerCase().trim(),value:entry});  
            }else{
                emptyProperty.push(entry);
           }
        }else{
            nullProperty.push(entry);
        }
    });

      sortedList.sort(function(a,b){
           return a.key < b.key ? -1 : 1;
         //return a.key < b.key?-1:1;   // Asc 
         //return a.key < b.key?1:-1;  // Desc
      });


    $.each(sortedList,function(key,entry){
        tempObject[tempObject.length] = entry.value;
     });

    if(emptyProperty.length>0){
        tempObject.concat(emptyProperty);
    }
    if(nullProperty.length>0){
        tempObject.concat(nullProperty);
    }
    console.timeEnd("Sorting");
    return tempObject;
}
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.