Given a key, I want to find the next property in an object. I can not rely on the keys to be ordered or sequential (they're uuids). Please see below for trivial example of what I want:
var db = {
a: 1,
b: 2,
c: 3
}
var next = function(db, key) {
// ???
}
next(db, 'a'); // I want 2
next(db, 'b'); // I want 3
I also want a prev() function, but I'm sure it will be the same solution.
This seems like such a trivial problem but I can't for the life of me figure out how to do it.
Happy for the solution to use underscore.js or be written in coffeescript :)
The correct answer is: you can't do that, as objects are unordered as per ECMAScript's spec.
I'd recommend that you use an ordered structure, like an array, for the purpose of the problem:
var db = [
{key: 'a', value: 1},
{key: 'b', value: 2},
{key: 'c', value: 3}
];
Then the next
function can be something like:
var next = function(db, key) {
for (var i = 0; i < db.length; i++) {
if (db[i].key === key) {
return db[i + 1] && db[i + 1].value;
}
}
};
In case key
does not exist on db
or it was the last one, next
returns undefined
. if you're never going to ask for the next of the last item, you can simplify that function by removing the ternary &&
operator and returning db[i + 1].value
directly.
You can also use some of Underscore.js utility methods to make next
simpler:
var next = function(db, key) {
var i = _.pluck(db, 'key').indexOf(key);
return i !== -1 && db[i + 1] && db[i + 1].value;
};
(in this case next
could return false
sometimes... but it's still a falsy value :))
Now, a more pragmatic answer could be that, as most browsers will respect the order in which an object was initialized when iterating it, you can just iterate it with a for in
loop as the other answers suggest. I'd recommend using Object.keys
to simplify the job of iterating over the array:
// Assuming that db is an object as defined in the question.
var next = function(db, key) {
var keys = Object.keys(db)
, i = keys.indexOf(key);
return i !== -1 && keys[i + 1] && db[keys[i + 1]];
};