2013-08-22 37 views
5

Tôi có lớp Items sau:Lọc danh sách lớn dựa trên thời gian ngày

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

} 

và sau đó trong mã của tôi Tôi có List<Item> items chứa A LOT các mặt hàng loại Item, câu hỏi của tôi là những gì bạn đề nghị là tốt nhất chiều/thực hành phân loại/lọc các mục trong danh sách dựa trên CreatedDate cho các tình huống sau:

  • tất cả các mục mà CreatedDate là trước ngày x
  • tất cả các mục wher e các CreatedDate sau ngày x
  • tất cả các mục mà CreatedDate giữa ngày x và y ngày

T.B. Còn nếu tôi cũng sẽ đề cập đến thời gian? Giống như trước/sau/giữa ngày x thời gian y?

+0

Tôi đã thử các DateTime.Compare trong cơ bản Nếu điều kiện ... nên chỉ muốn biết cái gì là aproach tối ưu ... –

+0

Điều này trông khá giống như một bài tập về nhà, nhưng không chắc chắn: P –

+0

Tôi sẽ không gọi 'DateTime.Compare', khi' DateTime' quá tải '>', '> =' vv một cách hữu ích. –

Trả lời

8

Bạn có thể sử dụng 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); 

Bạn có thể sử dụng một foreach hoặc các phương pháp như ToList để thực hiện truy vấn và thực hóa kết quả.

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

Bạn cần phải có một cái nhìn tại Enumerable METHODS

Đối lọc sử dụng Where

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

Đối Ordering

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

Tôi thực sự sẽ đặt nó trước khi thực hiện mệnh đề where cho thân thiện với dự đoán chi nhánh! :) –

+0

tôi chỉ nói cho anh ta các phương pháp làm việc. – Ehsan

0

IMHO cách thứ ba là OK.

Nhưng nếu bạn không muốn bộ lọc, bạn có thể triển khai phân trang khi bạn truy xuất danh sách của mình. Bởi vì nếu bạn đặt phạm vi ngày lớn, bạn không giải quyết được vấn đề về hiệu suất của mình.

2

Sử dụng 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); 

Đối với đặt hàng

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

Tất cả các phương pháp LINQ là rất lớn, nhưng họ lặp danh sách 3 lần. Nếu có thực sự nhiều mặt hàng, sau đó có lẽ là một cách cổ hủ sẽ hiệu quả hơn (có nghĩa là, nếu bạn muốn tất cả ba kịch bản cùng một lúc, nếu không thì câu trả lời LINQ là con đường để đi):

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

xét bạn đã một List<>, tôi đề nghị:

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

có sự khác biệt tinh tế giữa những gì tôi đề nghị và những gì người khác đã gợi ý.

Phương pháp .Where không "bộ nhớ cache" danh sách trả về, vì vậy nếu bạn làm:

var filtered = items.Where(condition); 

foreach (var item in filtered) 
{ 
} 

foreach (var item in filtered) 
{ 
} 

toàn bộ danh sách của bạn sẽ được phân tích hai lần để tìm kiếm các mục mà làm cho tình trạng hiện thực. Để giải quyết việc này "vấn đề" (đôi khi nó có thể là một vấn đề), bạn có thể thêm một .ToList() sau .Where()

Các List<>.FindAll() trả về một mới List<> chỉ với những mục đã chọn. Vì vậy, bạn có thể liệt kê nó bao nhiêu lần bạn muốn, bởi vì nó đã được "vật chất hóa".

0

Bạn có thể sử dụng 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(); 
} 

Prints:

foo1 foo2 foo3 foo4 foo5 foo6

Các vấn đề liên quan