Как получить предыдущий элемент списка <T>

1

У меня есть список вроде

var myList = new List<object> { 
    new { Day = "Sunday", ID = 15 },
    new { Day = "Monday", ID = 20 }, 
    new { Day = "Tuesday", ID = 80 } 
};

теперь я хотел бы получить предыдущий день данного ID. например, 80 понедельника и воскресенья должны быть результатом для 20. Список упорядочен по ID!

У меня есть простой способ определить дневную стоимость? идеальным было бы решение linq.

  • 7
    Как насчет использования LinkedList .
Теги:
linq
list

6 ответов

6
Лучший ответ
var result = myList.LastOrDefault(item => item.ID < 80);
3

Быстрый n грязный способ:

myList.Where(c => c.ID < currentId).OrderByDescending(c => c.ID)
     .Select(c => c.Day).FirstOrDefault();
1
myList.TakeWhile(o => o.ID <= givenID).Select(o => o.Day).LastOrDefault();

Это предполагает, что myList упорядочен. В противном случае вы можете просто OrderBy()

0

Не используйте var и object. Попробуй это:

private class ItemList
{

    /// <summary>
    /// Day
    /// </summary>
    public string Day { get; set; }

    /// <summary>
    /// ID
    /// </summary>
    public int ID { get; set; }

}

А также:

List<ItemList> myList = new List<ItemList> { 
    new ItemList() { Day="S", ID=10 },
    new ItemList() { Day="M", ID=20 },
    new ItemList() { Day="T", ID=30 },
};

foreach(ItemList key in myList)
{
    ItemList result = myList.FindLast(x=>x.ID<key.ID);
    if(result!=null)
    {
        MessageBox.Show("Prev ID: " + result.ID.ToString());
    }
}
0

(Основано на вычислении разницы с предыдущим элементом с LINQ)

для чистого пути linq, чтобы найти предыдущее значение

var value = myList.SelectWithPrevious((prev, cur) => new { prev = prev, cur= cur}).Where((w) => w.cur.ID == 80).First();
            Console.WriteLine(value.prev.Day);

расширение

public static IEnumerable<TResult> SelectWithPrevious<TSource, TResult> (this IEnumerable<TSource> source,Func<TSource, TSource, TResult> projection)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            yield break;
        }
        TSource previous = iterator.Current;
        while (iterator.MoveNext())
        {
            yield return projection(previous, iterator.Current);
            previous = iterator.Current;
        }
    }
}

Это дает больше, чем вам нужно. Но это может помочь в будущем.

0
var item = myList.Single(l => l.ID == 80);
var i = myList.IndexOf(item);
var j = (i - 1) % myList.Count;

var prevItem = myList[j];

Это получит элемент, который вы ищете, найдите его в списке, вычтите его (по модулю вы можете обернуть конец списка), а затем получите предыдущий элемент из списка по индексу.

Изменение: использование индекса, а не нечто вроде FindLast, позволяет вам не нуждаться в значениях идентификатора, которые должны быть в порядке возрастания с днями. например, понедельник может составлять 100 и вторник 15, и это не изменит ситуацию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню