2013-08-22 5 views
5

У меня есть следующие товары класс:фильтра большой список, основанные на время, дат

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;} 

} 

, а затем в моем коде я имею List<Item> items, содержащий A LOT элементов типа Item, мой вопрос, что вы порекомендовали как лучшие способ/практика сортировки/фильтрации элементов в списке на основе CreatedDate для следующих сценариев:

  • всех пунктов, где CreatedDate раньше даты х
  • всех элементов WHER Е CreatedDate после даты х
  • всех пунктов, где CreatedDate между датой х и даты у

P.S. А что, если я упомянул и время? Как и до/после/между датой x времени y?

+0

Я попытался DateTime.Compare в основной Если условие ... так просто хотелось узнать, что оптимальный aproach ... –

+0

Это выглядит как домашнее задание, но не уверен: P –

+0

Я бы не назвал 'DateTime.Compare', когда' DateTime' перегружает '>', '> =' и т. д. –

ответ

8

Вы можете использовать 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); 

Вы можете использовать foreach или методы, как ToList для выполнения запроса и материализовать результат.

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

Вы должны взглянуть на Enumerable METHODS

Для фильтрации используют в Where

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

Ordering Для

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

Я бы на самом деле заказал его, прежде чем делать предложение where для дружелюбия с учетом ветви! :) –

+0

Я просто рассказываю ему о методах творения. – Ehsan

0

ИМХО третий способ это нормально.

Но если вы не хотите фильтра, вы можете реализовать разбиение на страницы при извлечении списка. Потому что если вы установите большой диапазон дат, вы не решите проблему с производительностью.

2

Использование 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); 

Для заказа

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

Все подходы LINQ велики, но они просматривать список в 3 раза. Если на самом деле есть много пунктов, то, возможно, старомодный способ будет более эффективным (то есть, если вы хотите, чтобы все три сценария сразу, в противном случае ответы LINQ являются путь):

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

Учитывая, у вас есть List<>, я предлагаю:

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); 

есть тонкое различие между тем, что я предложил, и то, что другие предложили.

Метод .Where не «кэш» возвращаемый список, так что если вы делаете:

var filtered = items.Where(condition); 

foreach (var item in filtered) 
{ 
} 

foreach (var item in filtered) 
{ 
} 

весь ваш список будет проанализирован дважды для поиска предметов, которые делают условие истинно. Для того, чтобы решить эту «проблему» (иногда это может быть проблемой) вы можете добавить .ToList() после .Where()

List<>.FindAll() возвращает новый List<> только выбранные элементы. Поэтому вы можете перечислить его сколько раз вы хотите, потому что оно «материализовалось».

0

Вы можете использовать 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(); 
} 

Печать:

foo1 foo2 foo3 foo4 foo5 foo6

Смежные вопросы