Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigating to previous and next item in a Javascript object

I want to navigate up and down an JavaScript Object given an item of an object. An example object:

var items = {
   "5" : ["name", "link2"],
   "8" : ["name 2", "link 2"],
   "11" : ["name 3", "link 3"]
}

Now, given I have the item items["8"]. I want to get previous and next item respectively.

getItemBefore = function(index) {
    // index holds 8
    // should return "5"
}

getItemAfter = function(index) {
    // index hold 8
    // should return 11
}

How can I get those items?

like image 353
Starx Avatar asked Mar 03 '13 11:03

Starx


People also ask

How to navigate between nodes with JavaScript?

You can use the following node properties to navigate between nodes with JavaScript: A common error in DOM processing is to expect an element node to contain text. The element node <title> (in the example above) does not contain text.

How to dynamically choose items from an array in JavaScript?

Say you have an Array var arr = ['foo', 'bar', 'baz'];. If you want to dynamically choose items from this Array, you'll need a new variable. Let's call this i and give it a default value var i = 0;

What happens when user clicks the next button in image array?

when user clicks the next button the value of i increments by 1 and we are using the i as the index of images array to access the image element In same way when user clicks the previous button the value of i decrements by 1 and we are using the i as the index of images array to access the image element

How do I navigate the node tree in HTML?

With the HTML DOM, you can navigate the node tree using node relationships. According to the W3C HTML DOM standard, everything in an HTML document is a node: With the HTML DOM, all nodes in the node tree can be accessed by JavaScript. New nodes can be created, and all nodes can be modified or deleted.


2 Answers

Would an array of objects be more appropriate here? The example below could be wrapped in an object and making the nextItem() and prevItem() methods. With this you might also need some bounds checking.

var items = [];
items[0] = {index : '5', name : 'name', link : 'link2'};
items[1] = {index : '8', name : 'name 2', link : 'link 2'};
items[2] = {index : '11', name : 'name 3', link : 'link 3'};

//then access them like this
var nextItem = function (index) {
    var i = 0,
    max = items.length;

    for (i; i < max; i += 1) {
        if (items[i].index === index) {
            return items[i + 1];
        }
    }
    return 'not found';
};

var prevItem = function (index) {
    var i = 0,
    max = items.length;

    for(i; i < max; i += 1) {
        if (items[i].index === index) {
            return items[i - 1];
        }
    }
    return 'not found';
};

//the nextItem object after 5 is shown in the console. 
console.dir(nextItem('5'));
like image 112
adamS Avatar answered Sep 30 '22 18:09

adamS


The keys that an object holds can be retrieved as an array with Object.keys(<var>). The order of the keys in the array is arbitrary; you need to sort them before indexing. An option is the built-in sort() method for arrays, which is especially useful because custom comparison functions can be provided (see below). Default order is alphabetical.

Once you get the ordered array, you only need to look up where your item is in the array and return the next and previous elements from it:

var keys = Object.keys(items).sort();
var loc = keys.indexOf(item);

Given that loc > -1 (that is, the item exists):

  • Previous item: items[keys[loc-1]], but check that loc > 0 (it's not the first one).
  • Next item: items[keys[loc+1]], but check that loc < keys.length (it's not the last one).

Object.keys is compatible with Javascript 1.85+; here is a workaround for older browsers.

Alternative orderings

Numerical

If you want the keys to have a numerical order, use this comparison function:

var keys = Object.keys(items).sort( function(a,b) {
    return b - a;
});

Creation (or Modification) Time

If you want to work with creation order instead of alphanumeric, the items must hold their creation time. Something like:

<value>.index = Date.getTime();
items['<item>'] = <value>;

Then, the sort() method needs the following comparison function:

var keys = Object.keys(items).sort( function(a,b) {
    return b.index - a.index;
});

This can be easily extended to last modification ordering or similar.

Creation Order

Notice that the former solution only works if the items are created more than 1 ms apart, which would be suitable for user actions. If the items are added faster, use this instead of the timestamp:

<value>.index = Object.keys(items).length;

Or, alternatively, keep an external counter with the number of items in the object.

like image 35
lemonzi Avatar answered Sep 30 '22 19:09

lemonzi