แปลงสตริง [] ถึง int [] ในหนึ่งบรรทัดของรหัสโดยใช้ LINQ


273

ฉันมีอาร์เรย์ของจำนวนเต็มในรูปแบบสตริง:

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

ฉันต้องการอาร์เรย์ของจำนวนเต็ม 'ของจริง' ที่จะผลักดันมันต่อไป:

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

ฉันพยายามที่จะส่ง int และแน่นอนล้มเหลว:

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

ฉันสามารถทำต่อไป:

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

หรือ

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

แต่ทั้งคู่ดูน่าเกลียด

มีวิธีอื่นในการทำงานให้สำเร็จหรือไม่?


3
เกิดอะไรขึ้นกับการวนซ้ำในคอลเล็กชั่นเดียวการแปลงค่าและการเพิ่มเข้าไปในคอลเลคชั่นที่สอง ดูเหมือนจะชัดเจนสำหรับฉัน
Ed S.


1
เพียง FYI ฉันใช้คำถามนี้ที่นี่: stackoverflow.com/questions/1297325/…
Allen Rice


TryParse ไม่เร็วขึ้น (ยกเว้นกรณีที่สตริงของคุณไม่ถูกต้อง แต่ในกรณีนั้นคุณต้องการให้มีข้อยกเว้นแจ้งเตือนคุณ)
usr

คำตอบ:


609

รับอาร์เรย์คุณสามารถใช้Array.ConvertAllวิธีการ :

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

ขอบคุณ Marc Gravell ที่ชี้ให้เห็นว่าแลมบ์ดานั้นสามารถตัดออกได้ทำให้มีเวอร์ชั่นที่สั้นกว่าดังที่แสดงด้านล่าง:

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

โซลูชัน LINQ นั้นคล้ายกันยกเว้นคุณจะต้องมีการToArrayโทรพิเศษเพื่อรับอาร์เรย์:

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

4
ดี ไม่รู้ว่าอันไหน 1
อะไรต่อมิอะไร

รหัส IL ที่สร้างนี้จริง ๆ แล้วน้อยกว่าคำตอบของ Simon Fox, FWIW
อัลเลนไรซ์

80
ที่จริงแล้วคุณไม่ต้องการแลมบ์ดา ConvertAll(arr, int.Parse)เพียงพอแล้ว
Marc Gravell

1
แลมบ์ดาเป็นสิ่งจำเป็นใน VB.Net 2010: uArray = Array.ConvertAll (sNums.Split (","), ฟังก์ชั่น (i) UInteger.Parse (i))
BSalita

1
@Balita ไม่ใน VB.Net มันArray.ConvertAll(arr, AddressOf Integer.Parse)
Slai

31

แก้ไข: เพื่อแปลงเป็นอาเรย์

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

สิ่งนี้ควรทำเคล็ดลับ:

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

1
.ToArray () ที่จำเป็นเพื่อตอบสนองของ OP คำถาม
อะไรต่อมิอะไร

2
การเปลี่ยนแปลงที่จะ var int [] และผนวก .ToArray () ถ้าคุณต้องการมันเป็นอาร์เรย์ int
ไซมอนฟ็อกซ์

19

เพื่อหลีกเลี่ยงข้อยกเว้นด้วยต่อ.Parseไปนี้เป็น.TryParseทางเลือก

หากต้องการใช้เฉพาะองค์ประกอบที่สามารถแยกวิเคราะห์ได้:

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 }

หรือ

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

ทางเลือกที่ใช้0สำหรับองค์ประกอบที่ไม่สามารถแยกวิเคราะห์ได้:

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

หรือ

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

วิธีที่สอง: var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();เพียงคืนค่าดัชนี 0,1,2, ... แทนค่าจริง ทางออกที่ถูกต้องคืออะไรที่นี่?
Beetee

ขอบคุณ @Beetee ไม่แน่ใจว่าฉันคิดอะไรอยู่กับเรื่องนั้น ฉันแทนที่มันด้วยทางเลือกอื่น
Slai

@Slai: ขอบคุณ แต่สิ่งที่ไม่new int[0]? เมื่อฉันมีข้อความที่ผมไม่ได้รับ0ในอาร์เรย์ของฉัน ...
Beetee

@Beetee new int[0]เป็นอาร์เรย์ว่างเปล่า ตัวอย่างสองตัวอย่างแรกข้ามค่าที่ไม่สามารถแยกวิเคราะห์ได้และสองตัวอย่างสุดท้ายใช้0สำหรับค่าที่ไม่สามารถแยกวิเคราะห์ได้
Slai

@Slai: อาตอนนี้ฉันเข้าใจแล้ว new int[] {0}ผมผสมมันขึ้นกับ ขอบคุณ.
Beetee

12

คุณสามารถส่งอาเรย์สตริงไปยัง int array โดย:

var converted = arr.Select(int.Parse)

5
ดี! ขอบคุณ. และใน VB.NetDim converted = arr.Select(addressof Integer.Parse)
Mafu Josh

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

ต้องให้แน่ใจว่าคุณไม่ได้รับIEnumerable<int>ผลตอบแทน


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.