1

Assuming a list of objects, each with an ID, what's the most efficient way of building a carousel, so that each object knows what its previous and next item is. The Last Item's previousId will link to the first item. The first item's previousId will link to the last.

I need the ID of the previous and the ID of the next, as this will be used to populate next and previous buttons on a web page.

I know I could iterate over them, adding placeholders for _next and _prev id, but what's the most efficient way to do this?

I figure my object should look like this:

class Item {
    public int Id { get; set; }
    public string ItemName { get; set; }
    public int Next { get; set; }
    public int Prev { get; set; }
}

SO, if I have a List<Item> items how can I most efficiently add the previous and next IDs to each item?

    int _prev = items.LastOrDefault().id;
    int _next = items.Count > 1 ? items[1].id : _prev;
    foreach (var i in items) {
        i.prev = _prev;
        i.next = (_next < 
        _prev = i.id;
        //_next = ???
    }

I think I'm looking at this wrong way. Is there a better way of doing this?

Armstrongest
  • 15,181
  • 13
  • 67
  • 106
  • 4
    Just out of curiosity - why not just an indexer into a list or array? Just add/subtract one and check the bounds...? – Marc Gravell Jan 19 '11 at 17:40
  • I'm with @Marc Gravell if you used a List or OrderedList with the items in your order all you need to handle is making the list behave circularly. This is by far the most efficient IMO. – Chris Marisic Jan 19 '11 at 17:50
  • 3
    Despite getting the point, *most efficient endless loop* still makes me chuckle. – Anthony Pegram Jan 19 '11 at 17:51
  • Here's another vote for @Marc Gravell. – Wes P Jan 19 '11 at 18:04
  • @Marc. But, what if the IDs aren't sequential? – Armstrongest Jan 19 '11 at 18:31
  • Atomix what have ids got to do with a circular list? You just populate a list on the order you want it, like you do with next/prev. No ids involved. Then just look at list[i+1], but allowing for wrap around. You could even write a custom indexer that takes the positive modulus, so i+/-1 always works – Marc Gravell Jan 19 '11 at 18:37

2 Answers2

4

If you don't want to use LinkedList and willing to use indexes instead of foreach as Marc Gravel suggested:

int count = items.Length;
for(int index = 0; index < count; index ++)
{
  item.Next = items[(index + 1) % count];
  item.Prev = items[(index - 1 + count) % count];
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
3

Use a LinkedList to hold your objects.

dlock
  • 9,447
  • 9
  • 47
  • 67
  • 3
    Why not use `LinkedList` which is included in the framework? – Matthew Abbott Jan 19 '11 at 17:47
  • If I knew of it's existence, I wouldn't have mentioned it's implementation. Answer updated =] – dlock Jan 19 '11 at 17:48
  • I'll look into this. But am I able to link the end to the beginning with this structure? – Armstrongest Jan 19 '11 at 18:31
  • 1
    @Atømix: There's no real need to link from the end to the beginning (or from the beginning to the end). The list knows where its `First` and `Last` nodes are, so in your code you can say that if `CurrentNode == MyList.Last`, then the "next" node is `MyList.First`. – Jim Mischel Jan 19 '11 at 18:49
  • Cool, thanks Jim/deadlock. I ended up using Alexei's (more or less) for simplicity's sake, but I'm definitely looking into LinkedLists. – Armstrongest Jan 19 '11 at 19:03