Sirwan Afifi
Sirwan Afifi

Reputation: 10824

How can I move next/previous in List using LINQ?

I have this class :

public class City
{
    public City()
    {
        //
        // TODO: Add constructor logic here
        //
    }
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Image { get; set; }
}

and this is my list :

List<City> list = new List<City>(){
new City{Id=1,Title="city1",Description=""},
new City{Id=2,Title="city2",Description=""},
new City{Id=3,Title="city3",Description=""},
new City{Id=4,Title="city4",Description=""}

}

How can I move next or move previous in my List using LINQ ?

Upvotes: 0

Views: 15679

Answers (5)

Binary Worrier
Binary Worrier

Reputation: 51719

You want ElementAt, it's logically equivalent to using the list indexer property, and is potentially far faster than using Skip & Take at runtime as it contains a specific check to see if the sequence implements IList, if so it uses the indexer, if not it iterates over the sequence (similar to doing a Skip(n).Take(1))

var nameList = List<string>{"Homer", "Marge", "Bart", "Lisa", "Maggie"};
IEnumerable<string> nameSequence = nameList;

secondFromList = nameList[1];
secondFromSequence = nameSequence.ElemenetAt(1);

IList is implemented by all sorts of collections, arrays etc not just List<>

Upvotes: 7

jenson-button-event
jenson-button-event

Reputation: 18961

An extension method of @Xaruth's answer

public static T NextIf<T>(this IEnumerable<T> source, T current)
{
    var list = source.ToList();
    return list.Skip(list.IndexOf(current) + 1).Take(1).FirstOrDefault();
}

Upvotes: 2

psubsee2003
psubsee2003

Reputation: 8751

From your question:

How can I move next or move previous in my List using LINQ ?

and your comment on @mattytommo's (now deleted) answer

for example I have two button(next/pre) when I click on next I want to see next item in the list and ...

LINQ is not the right tool for this job. LINQ is designed to act on collections and allow you to quickly filter and select specific elements, and return a separate collection. It's not designed "view" a specific object and then let you move on to the next. It is a lot more powerful than that, but there are much better tools and methods to accomplish what you want.

One idea would be to simply store the current position and call a method to return the next element in the collection:

private int currentPosition = 1;

public City SelectNextCity()
{
    currentPosition++;
    return list[currentPosition];
    // in this context `list` would be a class-level field.
}

This is a very rough example. If you were to actually implement this, you would need to add some index checks to make sure currentPosition exists within the collection before calling it.

Upvotes: 2

pyrocumulus
pyrocumulus

Reputation: 9300

Not really LINQ, but I would suggest something like:

List<City> cityList;
public City Next(City current)
{
    int index = cityList.IndexOf(current);

    if (index < cityList.Count - 1)
        return cityList.ElementAt(index + 1);
    return current;
}

public City Previous(City current)
{
    int index = cityList.IndexOf(current);

    if (index >= 1)
        return cityList.ElementAt(index - 1);
    return current;
}

And starting out with cityList.First().

Edit: I have to agree with others stating that LINQ is definitely the wrong tool for this job. If it is not an absolute requirement, just use regular indexing for this problem. LINQ actually makes the solution a lot harder than it should be.

Upvotes: 5

Xaruth
Xaruth

Reputation: 4114

It's not the purpose to Linq to manipulate object like you want (see psubsee2003's answer)

But if you want (if you have to, with a gun on your head) :

    public City GetNext(City actual)
    {
        return list.Skip(list.IndexOf(actual) + 1).Take(1).FirstOrDefault();
    }

Upvotes: 2

Related Questions