2012-03-11 10 views
41

Na przykład następująceCzy istnieje sposób sortowania/zamawiania kluczy w obiektach JavaScript?

var data = { 
    'States': ['NSW', 'VIC'], 
    'Countries': ['GBR', 'AUS'], 
    'Capitals': ['SYD', 'MEL'] 
} 
for (var item in data) { 
    console.log(item); 
} 

drukuje

States 
Countries 
Capitals 

Czy istnieje sposób, aby sortować alfabetycznie, dzięki czemu drukuje

Capitals 
Countries 
States 
+0

Warto zobaczyć: https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – aymericbeaumet

+1

Możliwy duplikat [Sort JavaScript Object przez key] (http: // stackoverflow .com/questions/5467129/sort-javascript-object-by-key) – ShadowRanger

Odpowiedz

75

Nie obrębie samego obiektu: Zbiór nieruchomego obiekt jest nieuporządkowany.

Jedną z rzeczy, którą można zrobić, to użyć Object.keys() i posortować tablicę, a następnie ją powtórzyć.

Object.keys(data) 
     .sort() 
     .forEach(function(v, i) { 
      console.log(v, data[v]); 
     }); 

Patches (implementacje) dla przeglądarek, które nie obsługują ECMAScript 5th edition:

+1

Warto dodać, że .sort() można zastąpić przez .replace(), jeśli chcesz odwrócić kolejność sortowania. Również sort() i reverse() akceptują funkcje porównania jako argumenty, co pozwala na dokładne dostrojenie sortowania. http://www.w3schools.com/jsref/jsref_sort.asp –

+2

@CharlesJaimet: Nie jestem pewien, co masz na myśli przez '.replace()'. Czy chodziło Ci o '.reverse()'? To rzeczywiście może być użyte, ale tylko jeśli chcesz, aby obecne zamówienie zostało odwrócone. Jeśli uporządkowana kolejność ma zostać odwrócona, najpierw należy ją posortować. Metoda '.s()' faktycznie akceptuje funkcję, ale '.reverse()' nie. –

+0

Dzięki @Squint. Pisząc zbyt szybko, myśląc zbyt wolno. :) –

8

Tak, jest. Nie w standardzie ECMAScript, ale obsługiwany przez przeglądarki i Node.js i wygląda na stabilny. Zobacz https://stackoverflow.com/a/23202095/645715.

EDIT: Zwraca obiekt, w którym są uporządkowane klucze. Możesz użyć Object.keys(...), aby uzyskać uporządkowane klucze z obiektu.

Po co martwić się o kolejność kluczy obiektu? Różnica może mieć znaczenie w niektórych aplikacjach, takich jak przetwarzanie XML z xml2js, które reprezentuje XML jako obiekty zagnieżdżone i używa znaczników XML jako kluczy mieszających.

Istnieje kilka uwag:

  • klucze, które wyglądają jak liczb pojawiają się pierwsze w kolejności numerycznej.
  • Klucze, które wyglądają jak ciągi, pojawiają się w kolejnej kolejności w kolejności reklamowej.
  • tym celu zgłasza Object.keys(obj)
  • celu, jak donosi for (var key in obj) {...} mogą różnić się w Safari Firefox

Funkcja zwraca się obiekt z kluczy sortowanych wstawiony w porządku alfabetycznym:

function orderKeys(obj, expected) { 

    var keys = Object.keys(obj).sort(function keyOrder(k1, k2) { 
     if (k1 < k2) return -1; 
     else if (k1 > k2) return +1; 
     else return 0; 
    }); 

    var i, after = {}; 
    for (i = 0; i < keys.length; i++) { 
    after[keys[i]] = obj[keys[i]]; 
    delete obj[keys[i]]; 
    } 

    for (i = 0; i < keys.length; i++) { 
    obj[keys[i]] = after[keys[i]]; 
    } 
    return obj; 
} 

Oto szybki test:

var example = { 
     "3": "charlie", 
     "p:style": "c", 
     "berries": "e", 
     "p:nvSpPr": "a", 
     "p:txBody": "d", 
     "apples": "e", 
     "5": "eagle", 
     "p:spPr": "b" 
    } 

var obj = orderKeys(example); 

ten zwraca

{ '3': 'charlie', 
    '5': 'eagle', 
    apples: 'e', 
    berries: 'e', 
    'p:nvSpPr': 'a', 
    'p:spPr': 'b', 
    'p:style': 'c', 
    'p:txBody': 'd' } 

Następnie można dostać zamówione klucze jak:

Object.keys(obj) 

Które zwraca

["3", "5", "apples", "berries", "p:nvSpPr", "p:spPr", "p:style", "p:txBody"] 
-1

Jeśli konwersja do tablicy nie pasuje do szablonu i wiesz klucze twojego obiektu możesz również zrobić coś takiego:

W twoim kontrolerze zdefiniuj tablicę z t he klawisze w odpowiedniej kolejności:

this.displayOrder = [ 
    'firstKey', 
    'secondKey', 
    'thirdKey' 
]; 

W szablonie powtórzyć klucze swojej displayorder a następnie użyć NG-init odesłanie do obiektu.

<div ng-repeat="key in ctrl.displayOrder" ng-init="entry = ctrl.object[key]"> 
    {{ entry.detail }} 
</div> 
Powiązane problemy