Belden
Belden

Reputation:

Get Next and Previous Elements in JavaScript array

I have a large array, with non-sequential IDs, that looks something like this:

PhotoList[89725] = new Array();
PhotoList[89725]['ImageID'] = '89725';
PhotoList[89725]['ImageSize'] = '123';
PhotoList[89726] = new Array();
PhotoList[89726]['ImageID'] = '89726';
PhotoList[89726]['ImageSize'] = '234';
PhotoList[89727] = new Array();
PhotoList[89727]['ImageID'] = '89727';
PhotoList[89727]['ImageSize'] = '345';
Etc....

I'm trying to figure out, given an ID, how can I can get the next and previous ID... So that I could do something like this:

<div id="current">Showing You ID: 89726 Size: 234</div>
Get Prev Get Next

Obviously, if we're at the end or beginning of the array we just a message...

Upvotes: 4

Views: 25622

Answers (8)

Alireza Alallah
Alireza Alallah

Reputation: 2544

you can use grep function and calculate prev or next item of specified array:

object = $.grep(data, function(e) {
            if(e.id == yourId) {
                return data[data.indexOf(e) + 1]; // or -1 for prev item
            }
     });

Upvotes: -1

Monzur
Monzur

Reputation: 1435

i think your image list will come from DB so you may can try this code, this code is working for me.

<?
    $prev="";
    $next="";
    $cur=0;
    $i=0;
    $pid=$_GET['pid'];
    while($rowcon=mysql_fetch_assoc($result))
    {       
        $arr[$i]=$rowcon['pid'];
        if($rowcon['pid']==$pid)
        {
            $cur=$i;
        }
        $i++;
    }   
    if($cur<$num_rows)
        $next=$arr[$cur+1];
    else
        $next="";
    if($cur>0)
        $prev=$arr[$cur-1];
    else
        $prev="";
    echo $prev."   ".$cur."   ".$next;
?>

Upvotes: -3

Rene
Rene

Reputation: 1

var sibNum = 0;
var sibList = [];
var prevSiblingID = false;
for (n in w) {
   sibNum++;
   sibList[n] = {
      title : n,
      prevSiblingID : prevSiblingID
   };
       if (prevSiblingID) {
          sibList[prevSiblingID].nextSiblingID = n;
   }
   prevSiblingID = n;
};
sibList[prevSiblingID].nextSiblingID = false;

Upvotes: 0

Stewart
Stewart

Reputation: 3161

I agree with the rest quotes you should be using objects not an array. Also make sure you create new arrays using the literal notation and not the new keyword with built in types. The new keyword is bad news and you could clobber the global object. Check out JSLint.

var a = new Array(); //bad dont use
var a = []; //this is the best way to create a new array
var o = {}; //create new objects like this

As for the problem at hand. Why not write a simple container that has its own internal counter?

function PhotoListContainer(PhotoList)
{
    if(PhotoList === undefined)
        throw("no photo list");

    this.counter = 0;
    var self = this;

    this.current = function(){
         return PhotoList[self.counter];
    };

    this.next = function(){
        return PhotoList[self.counter + 1];
    };

    this.prev = function(){
        return PhotoList[self.counter - 1];
    };

    // You could even write a function that loops each value from the current counter :)
    this.each_from_counter = function(callback){
        for(var i = self.counter; i < PhotoList.length; i++)
        {
             callback(PhotoList[i], i);
             self.counter++;
        }        
    };

}

//use 

var pc = new PhotoListContainer(PhotoList);
pc.counter = 500;
pc.next(); //returns the 501st object
pc.prev(); //returns the 499th object
pc.each_from_counter(function(photo, index){
     photo.somehting;
});

Upvotes: 1

JamesM-SiteGen
JamesM-SiteGen

Reputation: 820

No arrays at all are better..

images = {
    0: {
        size: 12345, /* dont realy need as you can use JS to mesure the size. */
        title: "day 1 on holiday"
    },
    1: {
        size: 13549, /* dont realy need as you can use JS to mesure the size. */
        title: "day 2 on holiday"
    },
    2: {
        size: 16548, /* dont realy need as you can use JS to mesure the size. */
        title: "day 3 on holiday"
    },
}

for(x in images){
    /* x = "the id of the image." */
    url[] = "/images/" + x + ".png";
    title[] = images[x].title;
    size[] = images[x].size;
    console.log("File: " + url[x] + " , Title: " + title[x] + " , Size: " + size + "bytes")
}

Upvotes: 0

Jerry
Jerry

Reputation: 573

Based on your example the IDs are sequential... This is another way of writing your example. new Array() really isn't what you should be using because those are objects you are creating. Also, I left the numbers as strings, but I'm not sure why you would want to do that. You could add next and prev like kuy suggested

PhotoList[89725] = {ImageID: '89725',
                    ImageSize: '123'};
PhotoList[89725] = {ImageID: '89726',
                    ImageSize: '234',
                    Next: '89727',
                    Prev: '89725'};
PhotoList[89725] = {ImageID: '89727',
                    ImageSize: '345'};

All of these are accessible just like your other structure.

Upvotes: 5

kuy
kuy

Reputation: 964

Why don't you add properties 'Prev' & 'Next' to that array?

PhotoList[89725] = new Array();
PhotoList[89725]['Prev'] = 89724;
PhotoList[89725]['Next'] = 89726;
PhotoList[89725]['ImageID'] = '89725';
PhotoList[89725]['ImageSize'] = '123';

This is just 'doubly-linked list' data structure.

Upvotes: 6

Eli Courtwright
Eli Courtwright

Reputation: 193321

There's really no way other than to iterate through the possible ids sequentially until you find one which has an entry in your array. For example:

function findClosest(arr, id, increasing) {
    var step = increasing ? 1 : -1;
    for(var i=id+step; i>=0 && i<=max_id; i+=step)
        if( arr[id] )
            return id;
}

Obviously, this approach requires that you keep track of the max_id so that you don't iterate forever; here I assume that it's a global variable, but you might want to make it a parameter to the findClosest function. You'd call this function like so:

var prev = findClosest(arr, id, false);
var next = findClosest(arr, id, true);

Upvotes: 3

Related Questions