2010-10-28 35 views
9

phiên bản ngắn: Tôi đang tìm kiếm tương đương JavaScript của Perl củaiterating trên một đối tượng JavaScript trong thứ tự sắp xếp dựa trên giá trị quan trọng đặc biệt của một đối tượng con

for my $key (sort { $hash{$a}{foo} cmp $hash{$b}{foo} } keys %hash) { 
    # do something with $key 
} 

Xem chi tiết:

Tôi có một Đối tượng JSON bao gồm một loạt các đối tượng JSON khác có các thuộc tính giống hệt nhau, giống như một băm băm trong Perl: ví dụ:

var peopleobj = { 
    "0291" : { "Forename" : "Jeremy", "Surname" : "Dyson" }, 
    "0398" : { "Forename" : "Billy", "Surname" : "Bunter" }, 
    "6714" : { "Forename" : "Harry", "Surname" : "Peterson" }, 
    "9080" : { "Forename" : "Barry", "Surname" : "Mainwaring"} 
} 

Tôi muốn lặp qua các đối tượng i n peopleobj theo thứ tự của các giá trị họ, ví dụ: để in ra các tên theo thứ tự họ. Các giải pháp JavaScript hoặc jQuery đơn giản sẽ hoạt động trong ngữ cảnh mà trong đó điều này đang được triển khai.

Cảm ơn trước vì thời gian quý báu của bạn.

+0

Rất cám ơn Daniel - điều đó thực sự hữu ích! – Jonah

+1

Chỉ cần một chi tiết: điều đó không được gọi là một đối tượng JSON, mà là một đối tượng JavaScript; JSON chỉ là một ký hiệu của một đối tượng JavaScript. –

+0

Cảm ơn bạn đã làm rõ, được đánh giá cao. Ghi nhận hợp lệ! – Jonah

Trả lời

9

Câu hỏi thú vị ... Một giải pháp JavaScript đơn giản là tạo chỉ mục cho các đối tượng của bạn trong một mảng riêng biệt, dựa trên thuộc tính 'Surname'. Một cái gì đó như thế này :

var peopleobj = { 
    "0291" : { "Forename" : "Jeremy", "Surname" : "Dyson" }, 
    "0398" : { "Forename" : "Billy", "Surname" : "Bunter" }, 
    "6714" : { "Forename" : "Harry", "Surname" : "Peterson" }, 
    "9080" : { "Forename" : "Barry", "Surname" : "Mainwaring" } 
}; 

var index = []; 

// build the index 
for (var x in peopleobj) { 
    index.push({ 'key': x, 'Surname': peopleobj[x]['Surname'] }); 
} 

// sort the index 
index.sort(function (a, b) { 
    var as = a['Surname'], 
     bs = b['Surname']; 

    return as == bs ? 0 : (as > bs ? 1 : -1); 
}); 

Bây giờ bạn sẽ có thể để lặp qua index mảng của bạn:

for (var i = 0; i < index.length; i++) { 
    console.log(peopleobj[index[i]['key']]['Surname']); 
} 

quả (Tested trong Firebug console):

Bunter 
Dyson 
Mainwaring 
Peterson 

Bạn có thể muốn kết hợp nó thành một số đối tượng Iterator có thể sử dụng lại được, mặc dù sẽ rất khó để có được như terse như Perl:

// Our reusable Iterator class: 
function MyIterator (o, key) { 
    this.index = []; 
    this.i = 0; 
    this.o = o; 

    for (var x in o) { 
     this.index.push({ 'key': x, 'order': o[x][key] }); 
    } 

    this.index.sort(function (a, b) { 
     var as = a['order'], 
      bs = b['order']; 

     return as == bs ? 0 : (as > bs ? 1 : -1); 
    }); 

    this.len = this.index.length; 
} 

MyIterator.prototype.next = function() { 
    return this.i < this.len ? 
      this.o[this.index[this.i++]['key']] : 
      null; 
}; 

Sau đó, sử dụng nó như sau:

// Our JavaScript object: 
var peopleobj = { 
    "0291" : { "Forename" : "Jeremy", "Surname" : "Dyson" }, 
    "0398" : { "Forename" : "Billy", "Surname" : "Bunter" }, 
    "6714" : { "Forename" : "Harry", "Surname" : "Peterson" }, 
    "9080" : { "Forename" : "Barry", "Surname" : "Mainwaring" } 
}; 

// Build the Iterator object, using the 'Surname' field: 
var surnameIter = new MyIterator(peopleobj, 'Surname'); 

// Iterate: 
var i; 

while (i = surnameIter.next()) { 
    console.log(i['Surname'] + ' ' + i['Forename']); 
} 

Kết quả:

Bunter Billy 
Dyson Jeremy 
Mainwaring Barry 
Peterson Harry 

Bạn có thể muốn sử dụng phương pháp hasOwnProperty() để đảm bảo rằng các tài sản thuộc về đối tượng của bạn và không được kế thừa từ Object.prototype:

for (var x in peopleobj) { 
    if (peopleobj.hasOwnProperty(x)) { 
     index.push({ 'key': x, 'Surname': peopleobj[x]['Surname'] }); 
    } 
} 
+2

+1. Câu trả lời hay, mặc dù hàm so sánh được chuyển tới 'sort()' có nghĩa là trả về một số, không phải là một Boolean. Tôi muốn đề nghị một cái gì đó như 'function (a, b) {var as = a.Surname., Bs = b.Bên; trở lại như == bs? 0: (như> bs? 1: -1); } ' –

+0

@Tim: Cảm ơn, bạn nói đúng. Tôi sẽ cập nhật câu trả lời của mình. –

+0

Đây là một giải pháp tuyệt vời nhờ lời giải thích. Tôi đã sử dụng chuỗi được chuyển đổi này thành Ngày tháng trong các hàm sắp xếp và nhận chính xác những gì tôi cần. – Akers

Các vấn đề liên quan