JSON-Suche nach Schlüssel

76243
TomShreds

Ich habe meine Suche in der JSON-Sammlung immer so durchgeführt:

var data = [
    {
        "Key": "1111-1111-1111",
        "Email": "test@test.com"
    }
];

function getByKey(key) {
    var found = null;

    for (var i = 0; i < data.length; i++) {
        var element = data[i];

        if (element.Key == key) {
           found = element;
       } 
    }

    return found;
}

Aber ich habe mich immer gefragt, ob es einen besseren / optimalen Weg gibt.

Irgendwelche Vorschläge?

Bonusfrage: Wie kann ich eine JSON-Sammlung sortieren? Ich habe mit .sort()und eine Vergleichsfunktion gefunden. Ist das der beste Weg?

Antworten
8
Why aren't you using the Array.prototype.filter-method? [{key:"1", name="name"}, ..... ].filter(function(o){ return o.key==="1"}) Thomas Junk vor 7 Jahren 1
Apropos. Sie können einen "Bruch" einfügen, nachdem Sie das Element "gefunden" haben. Wenn Sie (wirklich) 1 Element haben, stimmt das überein. Dies würde Ihren Code für durchschnittliche Fälle beschleunigen. Thomas Junk vor 7 Jahren 0

2 Antworten auf die Frage

5
Joseph

Another way you can do it is to have the collection in an object, and use the primary identifier as key. This identifier is usually a unique identifier for that entity, like a user id.

This is way faster than iterating over an array in search for a match. As far as I remember, accessing via a key only takes one operation, O(1) while iterating through an array would depend on the length of the array. Worst case is that your match is at the tip of the array, thus O(n).

var data = {
  "1111-1111-1111" : {
    "Email": "test@test.com"
  }
};

//get by key
var key = "1111-1111-1111";
var oneOneOne = data[key];

oneOneOne.Email //test@test.com

This is only good when you try to get the set by the key. Otherwise, you'd have to resort to other arrangements for other retrievals.

As for sorting though, objects don't guarantee order, though browsers do sort them somehow. As far as I know, iterating through properties of an object in Firefox and Chrome yield different orders in the way they are arranged.

Welches setzt voraus, dass der Schlüssel einzigartig ist. Thomas Junk vor 7 Jahren 1
@ Lilith2k3 Yup. Wenn Sie sich jedoch den Code des OP ansehen, gibt 'getByKey' nur ein Ergebnis zurück. Daher können wir davon ausgehen, dass es eindeutig ist. Joseph vor 7 Jahren 0
Die Frage ist, ob der TO diese Tatsache absichtlich vernachlässigt hat. Bei mehreren Schlüsseln wäre das Ergebnis falsch, dh nur der letzte. Thomas Junk vor 7 Jahren 0
Dies funktioniert natürlich, vorausgesetzt, "getByKey" ist die einzige Suche, die das OP benötigt. Ich war dort, sobald ich andere Lookups brauchte, dies weicht vom Optimum ab. Daher ziehe ich meine vor, mit dem Vorteil, dass (1) nicht verändert wird, wie die "Daten" ankommen (dh als Array von Objekten), über die das OP die Kontrolle ausüben kann oder nicht, (2) es einmal durchläuft, wenn es nicht isn 'ist. Es ist wirklich so furchtbar teuer, (3) im Gegenzug erhalten Sie die Möglichkeit, verschiedene Nachschlagewörterbücher aus derselben Iteration zu erstellen, und (4) das Sortieren mit gutem alten Vanilla-Javascript `.sort ()`, das Arrays sortieren soll keine Objekte. Terry Young vor 7 Jahren 0
2
Terry Young

I tend to generate a lookup dictionary as soon as I have the data. So in any case I only need to iterate the data once.

Comparing with your approach, let's say we need to call getByKey() multiple times, the total cost of iterating the data might actually be higher.

I suppose which approach being more suitable really depends on your own application or design. But I also find myself sometimes generating different lookup dictionaries from the same set of data, and I would still only need to iterate the data once.

As for the .sort() bonus question, I would say that in terms of readability and code maintenance, yes, I would consider it one of the best ways of sorting a json collection.

var data = [
        {
            "Key": "2222-2222-2222",
            "Email": "a@test.com"
        },
        {
            "Key": "1111-1111-1111",
            "Email": "test@test.com"
        }
    ],
    lookup = {};

// generate the lookup table for reuse
data.forEach(function (el, i, arr) {
    lookup[el.Key] = el.Email;
});

// should return 'test@test.com'
console.log(lookup['1111-1111-1111']); 

// sort by Key
var keys = data.sort(function (a, b) {
    var c = a.Key,
        d = b.Key;
    return c > d ? 1 :
           d < c ? -1 :
           0;       
});
console.log(keys[0].Key); // should return '1111-1111-1111'

// sort by Email
var emails = data.sort(function (a, b) {
    var c = a.Email,
        d = b.Email;
    return c > d ? 1 :
           d < c ? -1 :
           0;       
});
console.log(emails[0].Key); // should return '2222-2222-2222'