Says I have this List : 1, 3, 5, 7, 9, 13
For example, given value is : 9, the previous item is 7 and the next item is 13
How can I achieve this using C#?
Using LINQ in one line and with circular search:
Next of
YourList.SkipWhile(x => x != NextOfThisValue).Skip(1).DefaultIfEmpty( YourList[0] ).FirstOrDefault();
Previous of
YourList.TakeWhile(x => x != PrevOfThisValue).DefaultIfEmpty( YourList[YourList.Count-1]).LastOrDefault();
This is a working example (link to the fiddle)
List<string> fruits = new List<string> {"apple", "banana", "orange", "raspberry", "kiwi"};
string NextOf = "orange";
string NextOfIs;
NextOfIs = fruits.SkipWhile(x => x!=NextOf).Skip(1).DefaultIfEmpty(fruits[0]).FirstOrDefault();
Console.WriteLine("The next of " + NextOf + " is " + NextOfIs);
NextOf = "kiwi";
NextOfIs = fruits.SkipWhile(x => x!=NextOf).Skip(1).DefaultIfEmpty(fruits[0]).FirstOrDefault();
Console.WriteLine("The next of " + NextOf + " is " + NextOfIs);
string PrevOf = "orange";
string PrevOfIs;
PrevOfIs = fruits.TakeWhile(x => x!=PrevOf).DefaultIfEmpty(fruits[fruits.Count-1]).LastOrDefault();
Console.WriteLine("The prev of " + PrevOf + " is " + PrevOfIs);
PrevOf = "apple";
PrevOfIs = fruits.TakeWhile(x => x!=PrevOf).DefaultIfEmpty(fruits[fruits.Count-1]).LastOrDefault();
Console.WriteLine("The prev of " + PrevOf + " is " + PrevOfIs);
I have implemented this by Inheriting the .Net List
public class NavigationList<T> : List<T>
{
private int _currentIndex = 0;
public int CurrentIndex
{
get
{
if (_currentIndex > Count - 1) { _currentIndex = Count - 1; }
if (_currentIndex < 0) { _currentIndex = 0; }
return _currentIndex;
}
set { _currentIndex = value; }
}
public T MoveNext
{
get { _currentIndex++; return this[CurrentIndex]; }
}
public T MovePrevious
{
get { _currentIndex--; return this[CurrentIndex]; }
}
public T Current
{
get { return this[CurrentIndex]; }
}
}
Using this becomes quite easy
NavigationList<string> n = new NavigationList<string>();
n.Add("A");
n.Add("B");
n.Add("C");
n.Add("D");
Assert.AreEqual(n.Current, "A");
Assert.AreEqual(n.MoveNext, "B");
Assert.AreEqual(n.MovePrevious, "A");
This can be done using LinkedList<T>
List<int> intList = new List<int> { 1, 3, 5, 7, 9, 13 };
LinkedList<int> intLinkedList = new LinkedList<int>(intList);
Console.WriteLine("Next Value to 9 "+intLinkedList.Find(9).Next.Value);
Console.WriteLine("Next Value to 9 " +intLinkedList.Find(9).Previous.Value);
//Consider using dictionary for frequent use
var intDictionary = intLinkedList.ToDictionary(i => i, i => intLinkedList.Find(i));
Console.WriteLine("Next Value to 9 " + intDictionary[9].Next.Value);
Console.WriteLine("Next Value to 9 " + intDictionary[9].Previous.Value);
Console.Read();
int index = list.IndexOf(9); // find the index of the given number
// find the index of next and the previous number
// by taking into account that
// the given number might be the first or the last number in the list
int prev = index > 0 ? index - 1 : -1;
int next = index < list.Count - 1 ? index + 1 : -1;
int nextItem, prevItem;
// if indexes are valid then get the items using indexer
// otherwise set them to a temporary value,
// you can also use Nullable<int> instead
nextItem = prev != -1 ? list[prev] : 0;
prevItem = next != -1 ? list[next] : 0;
Approach with ElementOrDefault()
https://dotnetfiddle.net/fxVo6T
int?[] items = { 1, 3, 5, 7, 9, 13 };
for (int i = 0; i < items.Length; i++)
{
int? previous = items.ElementAtOrDefault(i - 1);
int? current = items.ElementAtOrDefault(i);
int? next = items.ElementAtOrDefault(i + 1);
}
List<int> listInts = new List<int>();
listInts.AddRange(new int[] { 1, 3, 5, 7, 9, 13 });
int index = listInts.IndexOf(3); //The index here would be "1"
index++; //Check first if the index is in the length
int element = listInts[index]; //element = 5