2013-08-22 7 views
5

mam następujące klasy Pozycje:Filtr duża lista podstawie czasu data

public class Item 
{ 
    public Item() 
    { 
    } 

    public string Id {get; set;} 
    public string Name {get; set;} 
    public string Price {get; set;} 
    public DateTime CreatedDate {get; set;} 

} 

a następnie w moim kodu mam List<Item> items zawierający A LOT elementów typu Item, moje pytanie brzmi: co polecacie jako najlepszy sposób/praktyki sortowania/filtrowania pozycji na liście w oparciu o CreatedDate dla następujących scenariuszy:

  • wszystkie pozycje gdzie CreatedDate jest przed datą x
  • wszystkich elementów gdzi E CreatedDate po dacie x
  • wszystkie pozycje gdzie CreatedDate pomiędzy datą X i Y Data

PS: A co jeśli o tym pomyślę również o czasie? Podobnie jak przed/po/między datą x czasem y?

+0

Próbowałem DateTime.Compare w podstawowym Jeśli warunek ... więc chciałem tylko wiedzieć, co jest optymalne podejście ... –

+0

Wygląda to trochę jak zadanie domowe, ale nie jestem pewien: P –

+0

Nie nazwałbym 'DateTime.Compare', gdy' DateTime' przeładowuje '>', '> =' etc. –

Odpowiedz

8

Można użyć LINQ:

var beforeDateX = items 
    .Where(i => i.CreatedDate.Date < DateX); // remove the .Date if you want to include the time 
var afterDateX = items 
    .Where(i => i.CreatedDate.Date > DateX); 
var betweenDates = items 
    .Where(i => i.CreatedDate.Date >= DateX && i.CreatedDate.Date <= DateY); 

można użyć foreach lub metod jak ToList do wykonania zapytania i materializować wynik.

foreach(Item i in beforeDateX) 
    Console.WriteLine("Name:{0} CreatedDate:{1}", i.Name, i.CreatedAt); 
0

Trzeba spojrzeć na Enumerable METHODS

do filtrowania użyć Where

list.Where(x=>x.CreatedDate < yourDate).ToList(); 

Dla Ordering

list.OrderBy(x=>x.CreatedDate).ToList(); 
+0

Naprawdę zamówiłbym to zanim zrobię klauzulę where dla przyjazności przewidywania rozgałęzień! :) –

+0

Po prostu mówię mu metody robienia rzeczy. – Ehsan

0

IMHO trzecia droga jest OK.

Ale jeśli nie chcesz filtra, możesz zaimplementować paginację, gdy pobierzesz listę. Ponieważ jeśli umieścisz duży zakres dat, nie rozwiążesz problemu z wydajnością.

2

używać LINQ:

var itemsBefore = items.Where(i => i.CreatedDate <= timeBefore); 
var itemsAfter = items.Where(i => i.CreatedDate >= timeAfter); 
var itemsBetween = items.Where(i => i.CreatedDate >= timeStart && i.CreatedDate <= timeEnd); 

Dla zamawiania

var ordrered = items.OrderBy(i => i.CreatedDate); 
0

Wszystkie podejścia LINQ są świetne, ale iteracyjne Wykaz 3 razy. Jeśli istnieją naprawdę wiele elementów, to może staromodny sposób będzie bardziej efektywny (to znaczy, jeśli chcesz, aby wszystkie trzy scenariusze na raz, w przeciwnym razie odpowiedzi LINQ są do zrobienia):

List<Item> before = new List<Item>(); 
List<Item> after = new List<Item>(); 
List<Item> between = new List<Item>(); 

foreach (var item in Items) 
{ 
    if (item.CreatedDate <= timeBefore) 
    { 
    before.Add(item); 
    } 
    else if (item.CreatedDate >= timeAfter) 
    { 
    after.Add(item); 
    } 
    else 
    { 
    between.Add(item); 
    } 
} 
1

Biorąc pod uwagę, że masz List<>, proponuję:

List<Item> itemsBefore = items.FindAll(i => i.CreatedDate <= timeBefore); 
List<Item> itemsAfter = items.FindAll(i => i.CreatedDate >= timeAfter); 
List<Item> itemsBetween = items.FindAll(i => i.CreatedDate >= timeStart && i.CreatedDate <= timeEnd); 

istnieje subtelna różnica między tym, co zasugerowałem i co drugi sugerowali.

Sposób .Where nie „cache” zwrócona lista, więc jeśli zrobić:

var filtered = items.Where(condition); 

foreach (var item in filtered) 
{ 
} 

foreach (var item in filtered) 
{ 
} 

Twój cała lista będzie analizowana dwukrotnie, aby szukać przedmiotów, które sprawiają, że stan prawdą. Aby rozwiązać ten „problem” (czasami może to być problem) można dodać .ToList() po .Where()

List<>.FindAll() zwraca nowy List<> tylko z wybranych przedmiotów. Możesz więc wyliczyć ile razy chcesz, ponieważ zostało "zmaterializowane".

0

Można użyć LINQ Where:

static void Main(string[] args) 
{ 
    Item item1 = new Item() { CreatedDate = new DateTime(2010, 11, 10), Id = "1", Name = "foo1", Price = "10.00" }; 
    Item item2 = new Item() { CreatedDate = new DateTime(2010, 11, 11), Id = "2", Name = "foo2", Price = "11.00" }; 
    Item item3 = new Item() { CreatedDate = new DateTime(2010, 11, 12), Id = "3", Name = "foo3", Price = "12.00" }; 
    Item item4 = new Item() { CreatedDate = new DateTime(2010, 11, 13), Id = "4", Name = "foo4", Price = "13.00" }; 
    Item item5 = new Item() { CreatedDate = new DateTime(2010, 11, 14), Id = "5", Name = "foo5", Price = "14.00" }; 
    Item item6 = new Item() { CreatedDate = new DateTime(2010, 11, 15), Id = "6", Name = "foo6", Price = "15.00" }; 
    Item item7 = new Item() { CreatedDate = new DateTime(2010, 11, 16), Id = "7", Name = "foo7", Price = "16.00" }; 
    Item item8 = new Item() { CreatedDate = new DateTime(2010, 11, 17), Id = "8", Name = "foo8", Price = "17.00" }; 

    List<Item> items = new List<Item>(); 
    items.Add(item1); 
    items.Add(item2); 
    items.Add(item3); 
    items.Add(item4); 
    items.Add(item5); 
    items.Add(item6); 
    items.Add(item7); 
    items.Add(item8); 

    List<Item> filtered = ItemsBeforeDate(items, new DateTime(2010, 11, 16)); 
    foreach (Item i in filtered) 
    { 
     Console.Write(i.Name); 
    } 

    Console.Read(); 
} 

public static List<Item> ItemsBeforeDate(List<Item> items, DateTime beforeDate) 
{ 
    return items.Where(i => i.CreatedDate < beforeDate).ToList(); 
} 

public static List<Item> ItemsAfterDate(List<Item> items, DateTime afterDate) 
{ 
    return items.Where(i => i.CreatedDate > afterDate).ToList(); 
} 

public static List<Item> ItemsBetweenDates(List<Item> items, DateTime startDate, DateTime endDate) 
{ 
    return items.Where(i => i.CreatedDate >= startDate && i.CreatedDate <= endDate).ToList(); 
} 

Drukuje:

foo1 foo2 foo3 foo4 foo5 foo6