it-swarm.com.de

Wie kann ich ein Javascript-Objekt sortieren oder in ein Array konvertieren?

Ich habe einige JSON-Daten, die ich von einem Server bekomme. In meinem JavaScript möchte ich etwas sortieren. Ich denke, die sort () - Funktion wird das tun, was ich will.

Es scheint jedoch, dass JavaScript die JSON-Daten sofort nach Ankunft in ein Objekt konvertiert. Wenn ich versuche, die sort () -Methode zu verwenden, erhalte ich Fehler (mit Firebug zum Testen).

Ich habe mich im Netz umgesehen, und jeder scheint zu sagen, dass JSON-Objekte bereits JavaScript-Arrays sind und dass Objekte genauso wie Arrays behandelt werden können. Wie auf diese Frage , wo in einer der Antworten ein Mann sagt "Das Objekt ist Ihre Daten - Sie können darauf zugreifen, als würden Sie ein Array verwenden."

Das trifft jedoch nicht genau zu. JavaScript lässt mich nicht sort () für mein Objekt verwenden. Und da standardmäßig angenommen wird, dass sie alle dasselbe sind, scheint es nirgendwo Anweisungen zu geben, wie ein Objekt in ein Array konvertiert werden kann, oder erzwingen, dass JavaScript es als ein Objekt behandelt.

Also ... wie bekomme ich JavaScript, damit ich diese Daten als Array behandeln und sortieren kann?

Die Konsolenprotokollausgabe meines Objekts sieht folgendermaßen aus (ich möchte nach den Werten in der "Ebene" sortieren können):

OBJECT JSONdata

{ 
1: {
    displayName: "Dude1",
    email: "[email protected]<mailto:[email protected]>",
    lastActive: 1296980700, 
    level: 57, 
    timeout: 12969932837
}, 2: {
    displayName: "Dude2",
    email: "[email protected]<mailto:[email protected]>",
    lastActive: 1296983456,
    level: 28,
    timeout: 12969937382
}, 3: {
    displayName: "Dude3",
    email: "[email protected]<mailto:[email protected]>",
    lastActive: 1296980749,
    level: 99,
    timeout: 129699323459
} 
}
37
Questioner

Array.prototype.slice.call(arrayLikeObject)

ist die Standardmethode zum Konvertieren eines arrayähnlichen Objekts in ein Array.

Das funktioniert nur für das Objekt arguments. Das Konvertieren eines generischen Objekts in ein Array ist ein bisschen mühsam. Hier ist die Quelle von nderscore.js :

_.toArray = function(iterable) {
    if (!iterable)                return [];
    if (iterable.toArray)         return iterable.toArray();
    if (_.isArray(iterable))      return iterable;
    if (_.isArguments(iterable))  return slice.call(iterable);
    return _.values(iterable);
};

_.values = function(obj) {
    return _.map(obj, _.identity);
};

Es hat sich herausgestellt, dass Sie eine Schleife über Ihr Objekt ausführen und es selbst einem Array zuordnen müssen.

var newArray = []
for (var key in object) {
    newArray.Push(key);
}

Sie verwechseln die Konzepte von Arrays und "assoziativen Arrays". In JavaScript verhalten sich Objekte wie ein assoziatives Array, da Sie auf Daten im Format object["key"] zugreifen können. Sie sind keine echten assoziativen Arrays, da Objekte ungeordnete Listen sind.

Objekte und Arrays sind sehr unterschiedlich.

Ein Beispiel für die Verwendung von Unterstrichen:

var sortedObject = _.sortBy(object, function(val, key, object) {
    // return an number to index it by. then it is sorted from smallest to largest number
    return val;
});

Siehe Live-Beispiel

42
Raynos

Sie sollten in der Lage sein, ein JavaScript-Objekt in ein Array zu konvertieren ...

var obj = {
    '1': 'a',
    '2': 'b',
    '3': 'c'  
};

var arr = [];

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      arr.Push(obj[key]);  
    }
}

console.log(arr); // ["a", "b", "c"]

Siehe auf jsFiddle .

7
alex

Wenn Ihr JavaScript-Objekt ein array-ähnliches Objekt ist, d. H. Eine Objektinstanz mit einer gültigen numerischen length-Eigenschaft, können Sie dank der call-Methode viele native Array-Methoden direkt darauf verwenden . Zum Beispiel:

// Sorts the given objet in-place as if it was an array
Array.prototype.sort.call(yourObject);

Wenn Sie also die Anzahl der zu sortierenden Einträge kennen ( Wie Sie die Anzahl der Schlüssel/Eigenschaften eines Objekts in JavaScript effizient zählen können? ), können Sie Folgendes tun:

yourObject.length = theNumberOfEntries;
Array.prototype.sort.call(yourObject);
// Optionally: delete yourObject.length;

Beachten Sie, dass dadurch nur Eigenschaften sortiert werden, die mit "0", "1", "2", ... bis einschließlich length - 1 indiziert sind, wie in einem Array. Die anderen Eigenschaften des Objekts werden nicht neu angeordnet.

6
Luc125

Die meisten dieser Antworten verkomplizieren das Problem oder verwenden JQuery oder Underscore, wohingegen das OP diese nie angefordert hat.

Sie können ein Objekt folgendermaßen in ein Array konvertieren:

myArray= Object.keys(data).map(function(key) { return data[key] });

Und sortiere das Ergebnis so:

myArray.sort(function(x, y) {return x.level - y.level});

Wenn Sie die ID/den Index benötigen, müssen Sie noch etwas mehr tun:

Object.keys(data).map(function(key) { 
  var obj = data[key];
  obj.index = key;
  return obj 
});
5
andyhasit

Ich bin kürzlich über dieses Problem gestolpert, als ich versuche, ein Array von Objekten nach einer seiner Eigenschaften zu gruppieren, was zu einem Objekt führte, das ich daher nicht sortieren konnte. 

Konkret handelt es sich dabei um eine Reihe von Blogbeiträgen, die ich nach Jahr gruppieren und nach absteigenden Jahren sortieren lassen soll. Ich habe das Dienstprogramm von Unterstrich verwendet:

var grouped = _.groupBy(blogposts, function(post){
  var date = new Date(post.publication_date)
  return date.getFullYear()
})
//=> { 2010: [blogpost, blogpost,etc], 2011: [blogpost, etc] }

Als @Raynos erklärte, musste ich zuerst ein Array bekommen, bevor ich es sortieren konnte ... 

Es stellt sich heraus, dass Unterstrich (1.4) ein kleines Hilfsprogramm namens pairs enthält, das den {key: value} Ihres Objekts in einem Array von [key, value] abbildet. Das Äquivalent von:

var paired = _.map(grouped, function(val, key){
  return [key, val]
})
//=> [ [2010, [blogpost, blogpost, ...] ], [2011, [blogpost, blogpost, ...]]...]

Von da an können Sie leicht nach dem ersten Begriff jedes Paares sortieren. 

Hier ist das Endergebnis:

var grouped = _.groupBy(result.resource, function(resource){
  var date = new Date(resource.pub_date)
  return date.getFullYear() //+ "." + (date.getMonth()+1)
})

var paired = _.pairs(grouped)

var sorted = _.sortBy(paired, function(pairs){
  return -parseInt(pairs[0])
})

return sorted;
// Giving me the expected result:
//=> [ [2013, [blogpost, blogpost, ...] ], [2012, [blogpost, blogpost, ...]]...]

Ich bin sicher, dass es einen besseren und performanteren Weg gibt, aber von Ruby aus ist dieser Code für mich sofort verständlich.

2
charlysisto

jQuery bietet eine Map-Funktion, die jedes Element in einem Array oder Objekt durchläuft und die Ergebnisse in einem neuen Array darstellt. 

Vor jQuery 1.6 unterstützte $ .map () nur durchlaufende Arrays.

Wir können dies verwenden, um jedes Objekt wie folgt in ein Array zu konvertieren ...

  myArray = $.map(myObject, function (el) {
    return el;
  });

Aber ... Wenn die Callback-Funktion null oder undefined zurückgibt, lautet der Wert remove aus dem Array. In den meisten Fällen ist dies nützlich, kann jedoch zu Problemen führen, wenn Sie Nullwerte benötigen in myArray.

jQuery bietet eine Lösung dafür ... gibt den Wert als Array mit dem Einzelwert zurück

myArrayWithNulls = jQuery.map(myObject, function (el) {
  return [el];
});

Hier eine Geige, die die beiden Ansätze demonstriert: http://jsfiddle.net/chim/nFyPE/

http://jsperf.com/object-to-array-jquery-2

1
chim

Ich habe eine kleine Funktion zum rekursiven Konvertieren eines Objekts mit Eigenschaften, die auch Objekte sein können, in ein mehrdimensionales Array geschrieben. Dieser Code ist für die Methoden forEach und toArray abhängig von Unterstrich oder lodash.

function deepToArray(obj) {
    var copy = [];


    var i = 0;
    if (obj.constructor == Object ||
        obj.constructor == Array) {

        _.forEach(obj, process);

    } else {

        copy = obj;

    }


    function process(current, index, collection) {

        var processed = null;
        if (current.constructor != Object &&
            current.constructor != Array) {
            processed = current;
        } else {
            processed = deepToArray(_.toArray(current));
        }

        copy.Push(processed);

    }

    return copy;
}

Hier ist die Geige: http://jsfiddle.net/gGT2D/

Hinweis: Dies wurde geschrieben, um ein Objekt, das ursprünglich ein Array war, zurück in ein Array zu konvertieren, sodass alle Nicht-Array-Indexschlüsselwerte verloren gehen.

1
Isioma Nnodum