I always did my lookup in JSON collection like that:

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

But I always wondered if there was a better / more optimal way of doing this.

Any suggestions?

Bonus question: any way of sorting a JSON collection? I found with .sort() and a compare function. Is that the best way?

  • Why aren't you using the Array.prototype.filter-method? [{key:"1", name="name"}, ..... ].filter(function(o){ return o.key==="1"}) – Thomas Junk May 6 '13 at 19:33
  • By the way. You could insert a "break" after you "found" the element. If you (really) have 1 element, that matches. This would speed your code up for average cases. – Thomas Junk May 6 '13 at 20:04

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.

  • 1
    Which presumes, that the key is unique. – Thomas Junk May 6 '13 at 19:32
  • @Lilith2k3 Yup. But if you take a look at the OP's code, getByKey only returns one result, thus we could assume that it is unique. – Joseph May 6 '13 at 19:54
  • The question is, whether the TO has neglected that fact by intention. If there were multiple keys, the result would be false, i.e. only the last one. – Thomas Junk May 6 '13 at 20:02
  • This works of course, assuming getByKey is the only lookup the OP needs. I've been there, as soon as I needed different lookups, this deviates from the optimal. Hence, I prefer mine, with the benefit of (1) not altering how the data arrives (i.e. as an array of objects), which the OP might or might not have control over, (2) looping through it once isn't really so dreadfully expensive, (3) in exchange, you get the ability to create different lookup dictionaries from the same iteration, and (4) sorting with good ol' vanilla javascript .sort(), which is meant to sort arrays, not objects. – Terry Young May 7 '13 at 6:46

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'

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.