2010-01-18 79 views
22

Tôi có một List<int> và tôi muốn chuyển đổi nó thành List<double>. Có cách nào để làm điều này khác hơn là chỉ Looping qua List<int> và thêm vào một List<double> mới như vậy:C# Danh sách chuyển đổi <int> thành Danh sách <double>

List<int> lstInt = new List<int>(new int[] {1,2,3}); 
List<double> lstDouble = new List<double>(lstInt.Count);//Either Count or Length, I don't remember 

for (int i = 0; i < lstInt.Count; i++) 
{ 
    lstDouble.Add(Convert.ToDouble(lstInt[0])); 
} 

Có một cách ưa thích để làm điều này? Tôi đang sử dụng C# 4.0, vì vậy câu trả lời có thể tận dụng các tính năng ngôn ngữ mới.

+0

(đối với bản ghi, lưu ý rằng phương sai C# 4.0 sẽ không hoạt động trên các loại cụ thể ('List '), sẽ không hoạt động trên danh sách nói chung ('IList ') và sẽ không hoạt động giữa 'int' và 'double') –

Trả lời

28

Bạn có thể sử dụng phương pháp LINQ:

List<double> doubles = integers.Select<int, double>(i => i).ToList(); 

hay:

List<double> doubles = integers.Select(i => (double)i).ToList(); 

Ngoài ra, các lớp danh sách có một Phương pháp ForEach:

List<double> doubles = new List<double>(integers.Count); 
integers.ForEach(i => doubles.Add(i)); 
+0

Điều này cần phải được chọn (i => i) .ToList(); Có cách nào để sử dụng cú pháp <,> với biến 'Loại' thay vì int không? – Ames

+1

@Chris: Nó thực sự bình thường chỉ là 'số nguyên.Select (i => (double) i)' là thành ngữ. Nhưng không, generics là một tính năng biên dịch-thời gian - nếu bạn muốn sử dụng một loại chỉ được biết đến tại thời gian thực hiện, bạn sẽ cần phải sử dụng sự phản chiếu. Nhập động trong C# 4 có thể giúp bạn với điều đó, nhưng bạn phải đưa ra một ví dụ cụ thể hơn trước khi chúng tôi có thể nói chắc chắn. –

+0

Sử dụng bản trình diễn thứ hai, tôi có thể tạo danh sách phản chiếu kiểu gấp đôi, sau đó sử dụng công cụ foreach để thêm các mục từ danh sách dựa trên int. Khuyến mãi sẽ xảy ra và mọi thứ hạnh phúc sẽ xảy ra. Câu trả lời này thực sự đã giải quyết được vấn đề của tôi, nhưng những câu hỏi trên thì ngắn gọn hơn cho câu hỏi mà tôi đã hỏi. – Ames

8

Bạn có thể làm điều này bằng cách sử dụng phương pháp Select mở rộng:

List<double> doubleList = intList.Select(x => (double)x).ToList(); 
+0

nhưng vẫn chỉ là một vòng lặp dưới bìa, phải không? –

+0

@ Mì lúa mì, đó là chính xác. –

+0

Vì vậy, có bất kỳ điểm nào trong việc không chỉ sử dụng một vòng lặp? Hiệu suât khôn ngoan? – Ames

49

Bạn thể sử dụng Select theo đề nghị của người khác, nhưng bạn cũng có thể sử dụng ConvertAll:

List<double> doubleList = intList.ConvertAll(x => (double)x); 

này có hai ưu điểm:

  • Nó không đòi hỏi LINQ, vì vậy nếu bạn đang sử dụng .NET 2.0 và không muốn sử dụng LINQBridge, bạn vẫn có thể sử dụng nó.
  • Hiệu quả hơn: phương pháp ToList không biết kích thước của kết quả là Select, vì vậy có thể cần phải phân bổ lại bộ đệm khi nó đi. ConvertAll biết kích thước nguồn và đích, vì vậy nó có thể làm tất cả trong một lần. Nó cũng có thể làm như vậy mà không có sự trừu tượng của các trình vòng lặp.

Những khó khăn:

  • Nó chỉ làm việc với List<T> và mảng. Nếu bạn nhận được một đồng bằng IEnumerable<T> bạn sẽ phải sử dụng SelectToList.
  • Nếu bạn đang sử dụng LINQ nặng nề trong dự án của mình, có thể nhất quán hơn khi tiếp tục sử dụng nó ở đây.
+1

và có sẵn trong .NET 3.5 cũng như –

+0

Không phải ConvertAll chỉ là trình bao bọc cho biểu thức LINQ? –

+0

Có sự khác biệt nào với Chọn ngoại trừ việc hiển thị rõ ràng ý định của bạn hơn không? – VVS

0

Bạn có thể sử dụng Chọn hoặc Chuyển đổi tất cả. Hãy ghi nhớ rằng ConvertAll có sẵn trong Net 2.0 quá

2

Bạn có thể sử dụng phương pháp ConvertAll bên trong .Net Framework 2.0 đây là một ví dụ

 List<int> lstInt = new List<int>(new int[] { 1, 2, 3 }); 
     List<double> lstDouble = lstInt.ConvertAll<double>(delegate(int p) 
     { 
      return (double)p; 
     }); 
1

Bạn có thể sử dụng một nhóm phương pháp:

lstDouble = lstInt.Select(Convert.ToDouble) 
Các vấn đề liên quan