2010-10-28 35 views
9

短版的排序順序JavaScript對象:我在尋找的JavaScript相當於Perl的迭代基於子對象的特定鍵值

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

更多細節:

我有一個JSON對象其由一串具有相同的性質彼此,像散列在Perl的散列其他JSON對象中的:例如:

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

我想通過對象來迭代我ñpeopleobj按姓氏的順序,例如按姓氏順序打印姓名。普通的JavaScript或jQuery解決方案將在正在部署的環境中工作。

在此先感謝您寶貴的時間。

+0

非常感謝丹尼爾 - 這真的很有用! – Jonah 2010-10-28 11:09:09

+1

只是一個細節:那個東西不叫做JSON對象,而是一個JavaScript對象; JSON只是一個JavaScript對象的符號。 – 2010-10-28 12:42:14

+0

感謝您的澄清,非常感謝。正式注意! – Jonah 2010-11-03 10:08:45

回答

9

有趣的問題...一個普通的JavaScript解決方案是基於'Surname'屬性在單獨的數組中創建對象的索引。事情是這樣的:

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

現在你就可以在你的index數組遍歷:

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

結果(在Firebug控制檯測試):

Bunter 
Dyson 
Mainwaring 
Peterson 

您可能想要將其包裝成某種可重用的Iterator對象,儘管它很難像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; 
}; 

然後按如下方式使用它:

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

結果:

Bunter Billy 
Dyson Jeremy 
Mainwaring Barry 
Peterson Harry 

您可能需要使用hasOwnProperty()方法,以確保財產屬於您的對象,而不是從Object.prototype繼承:

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

+1。很好的答案,儘管傳遞給sort()的比較函數應該返回一個數字,而不是布爾值。我建議像'function(a,b){var as = a.Surname。,bs = b.Surname;返回爲== bs? 0:(as> bs?1:-1); }' – 2010-10-28 11:13:35

+0

@Tim:謝謝,你說得對。我會更新我的答案。 – 2010-10-28 11:15:05

+0

感謝您的解釋,這是一個很好的解決方案。我在排序函數中使用了這個加上轉換後的字符串到Date,並得到了我所需要的。 – Akers 2012-01-09 16:30:56