Reputation: 10824
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
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
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
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
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
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