Chuyển đổi chuỗi [] thành int [] trong một dòng mã bằng LINQ


273

Tôi có một mảng các số nguyên ở dạng chuỗi:

var arr = new string[] { "1", "2", "3", "4" };

Tôi cần một loạt các số nguyên 'thực' để đẩy nó đi xa hơn:

void Foo(int[] arr) { .. }

Tôi đã cố gắng để int int và tất nhiên nó đã thất bại:

Foo(arr.Cast<int>.ToArray());

Tôi có thể làm tiếp theo:

var list = new List<int>(arr.Length);
arr.ForEach(i => list.Add(Int32.Parse(i))); // maybe Convert.ToInt32() is better?
Foo(list.ToArray());

hoặc là

var list = new List<int>(arr.Length);
arr.ForEach(i =>
{
   int j;
   if (Int32.TryParse(i, out j)) // TryParse is faster, yeah
   {
      list.Add(j);
   }
 }
 Foo(list.ToArray());

nhưng cả hai trông xấu xí.

Có cách nào khác để hoàn thành nhiệm vụ?


3
Có gì sai khi chỉ lặp đi lặp lại qua một bộ sưu tập, chuyển đổi giá trị và thêm nó vào thứ hai? Có vẻ khá rõ ràng trong ý định với tôi.
Ed S.


1
Chỉ cần FYI, tôi đang sử dụng câu hỏi này tại đây: stackoverflow.com/questions/1297325/ cấp
Allen Rice


TryPude không nhanh hơn (trừ khi chuỗi của bạn không hợp lệ, nhưng trong trường hợp đó bạn muốn ngoại lệ cảnh báo bạn).
usr

Câu trả lời:


608

Cho một mảng bạn có thể sử dụng Array.ConvertAllphương thức :

int[] myInts = Array.ConvertAll(arr, s => int.Parse(s));

Cảm ơn Marc Gravell đã chỉ ra rằng lambda có thể được bỏ qua, mang lại một phiên bản ngắn hơn được hiển thị dưới đây:

int[] myInts = Array.ConvertAll(arr, int.Parse);

Một giải pháp LINQ cũng tương tự, ngoại trừ bạn sẽ cần thêm ToArraycuộc gọi để có được một mảng:

int[] myInts = arr.Select(int.Parse).ToArray();

4
Đẹp. Không biết cái đó. +1
tiêu

Mã IL mà mã này tạo ra thực sự ít hơn câu trả lời của Simon Fox, FWIW
Allen Rice

80
Thật ra, bạn không cần lambda; ConvertAll(arr, int.Parse)là đủ
Marc Gravell

1
Lambda là cần thiết trong VB.Net 2010: uArray = Array.Convert ALL (sNums.Split (","), Function (i) UInteger.Pude (i))
BSalita

1
@BSalita Không, trong VB.Net nóArray.ConvertAll(arr, AddressOf Integer.Parse)
Slai

31

EDIT: để chuyển đổi sang mảng

int[] asIntegers = arr.Select(s => int.Parse(s)).ToArray();

Cái này cần phải dùng mẹo:

var asIntegers = arr.Select(s => int.Parse(s));

1
.ToArray () được yêu cầu để đáp ứng câu hỏi của OP
tiêu

2
thay đổi var thành int [] và nối thêm .ToArray () nếu bạn cần nó dưới dạng một mảng int
Simon Fox

19

Để tránh ngoại lệ với .Parse, đây là một số .TryParselựa chọn thay thế.

Để chỉ sử dụng các yếu tố có thể được phân tích cú pháp:

string[] arr = { null, " ", " 1 ", " 002 ", "3.0" };
int i = 0; 
var a = (from s in arr where int.TryParse(s, out i) select i).ToArray();  // a = { 1, 2 }

hoặc là

var a = arr.SelectMany(s => int.TryParse(s, out i) ? new[] { i } : new int[0]).ToArray();

Các lựa chọn thay thế sử dụng 0cho các yếu tố không thể được phân tích cú pháp:

int i; 
var a = Array.ConvertAll(arr, s => int.TryParse(s, out i) ? i : 0); //a = { 0, 0, 1, 2, 0 }

hoặc là

var a = arr.Select((s, i) => int.TryParse(s, out i) ? i : 0).ToArray();

C # 7.0 :

var a = Array.ConvertAll(arr, s => int.TryParse(s, out var i) ? i : 0);

Giải pháp thứ hai: var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();chỉ trả về các phân 0,1,2, ... thay vì các giá trị thực. Giải pháp nào đúng ở đây?
Củ cải

Cảm ơn @Beetee. Không chắc tôi đã nghĩ gì với điều đó. Tôi đã thay thế nó bằng một sự thay thế khác.
Slai

@Slai: Cảm ơn. Nhưng làm new int[0]gì? Khi tôi có văn bản, tôi không nhận được tin nhắn 0của mình ...
Beetee

@Beetee new int[0]là một mảng int trống. Hai ví dụ đầu tiên bỏ qua các giá trị không thể được phân tích cú pháp và hai ví dụ cuối sử dụng 0cho các giá trị không thể được phân tích cú pháp.
Slai

@Slai: Ah bây giờ tôi hiểu rồi. Tôi trộn nó lên với new int[] {0}. Cám ơn.
Củ cải

12

bạn có thể chỉ cần truyền một mảng chuỗi thành int mảng bằng cách:

var converted = arr.Select(int.Parse)

5
đẹp! cảm ơn bạn. Và trong VB.NetDim converted = arr.Select(addressof Integer.Parse)
Mafu Josh

3
var asIntegers = arr.Select(s => int.Parse(s)).ToArray(); 

Phải chắc chắn rằng bạn sẽ không nhận được IEnumerable<int>lợi nhuận


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.