2010-10-28 20 views
9

Krótka wersja: szukam odpowiednika JavaScript w PerlIteracja nad obiektu JavaScript w porządku sortowania w oparciu o szczególnej wartości klucza obiektu dziecięcej

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

Więcej szczegółów:

mam obiekt JSON, który składa się z bandą innych obiektów JSON, które mają identyczne właściwości do siebie, jak hash mieszań w Perl: np:

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

Chcę iterację obiektów i n peopleobj w kolejności nazwisk, np. aby wydrukować nazwiska w kolejności występowania. Zwykłe rozwiązania JavaScript lub jQuery będą działać w kontekście, w którym jest wdrażany.

Z góry dziękuję za cenny czas.

+0

Wielkie dzięki Daniel - to naprawdę przydatne! – Jonah

+1

Tylko jeden szczegół: rzecz ta nie jest nazywana obiektem JSON, ale obiektem JavaScript; JSON jest po prostu notacją obiektu JavaScript. –

+0

Dzięki za wyjaśnienia, bardzo docenione. Zanotowano! – Jonah

Odpowiedz

9

Interesujące pytanie ... Jednym z prostych rozwiązań JavaScript jest utworzenie indeksu dla obiektów w osobnej tablicy, w oparciu o właściwość 'Surname'. Coś takiego :

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

Teraz będzie można iteracyjne nad index tablicy:

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

wynik (Testowany w konsoli Firebug):

Bunter 
Dyson 
Mainwaring 
Peterson 

Użytkownik może chcesz zawinąć to w jakiś obiekt wielokrotnego użytku Iterator, chociaż byłoby trudno uzyskać tak zwięzłe jak 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; 
}; 

następnie używać go w sposób następujący:

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

Wynik:

Bunter Billy 
Dyson Jeremy 
Mainwaring Barry 
Peterson Harry 

Możesz użyć metody hasOwnProperty() aby upewnić się, że właściwości należą do obiekt i nie są dziedziczone od Object.prototype:

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

+1. Dobra odpowiedź, chociaż funkcja porównania przekazywana do 'sort()' ma zwracać liczbę, a nie wartość logiczną. Sugerowałbym coś w stylu 'function (a, b) {var as = a.Surname., Bs = b.Swag; return as == bs? 0: (as> bs? 1: -1); } ' –

+0

@Tim: Dzięki, masz rację. Zaktualizuję moją odpowiedź. –

+0

To świetne rozwiązanie, dzięki za wyjaśnienie. Użyłem tego oraz przekonwertowanego ciągu na Date w funkcjach sortowania i otrzymałem dokładnie to, czego potrzebowałem. – Akers

Powiązane problemy