การแปลง List <int> เป็นสตริงที่คั่นด้วยลูกน้ำ


116

มีวิธีรับ List และแปลงเป็นสตริงที่คั่นด้วยลูกน้ำหรือไม่?

ฉันรู้ว่าฉันสามารถวนซ้ำและสร้างมันได้ แต่ฉันคิดว่าพวกคุณบางคนมีวิธีที่เจ๋งกว่านี้ไหม?

ฉันต้องการเรียนรู้ 'เทคนิค' ประเภทนี้จริงๆดังนั้นโปรดอธิบายหรือเชื่อมโยงไปยังเอกสารเกี่ยวกับวิธีการที่คุณใช้

คำตอบ:


189
List<int> list = ...;
string.Join(",", list.Select(n => n.ToString()).ToArray())

7
ฉลาด แต่ช้าและป่องเพราะจัดสรรหนึ่งสตริงต่อองค์ประกอบ การใช้ StringBuilder จะมีประสิทธิภาพมากขึ้น
Steven Sudit

3
จากสิ่งที่ฉันเห็นออนไลน์ (ค้นหาอย่างรวดเร็ว) String.Join เร็วกว่าการใช้ StringBuilder
Yuriy Faktorovich

3
stackoverflow.com/questions/585860/… , คุณไม่ถูกต้อง Steven
Yuriy Faktorovich

6
ฉันคิดว่าสตีเวนอ้างถึงส่วน n ToString () มากกว่า String เข้าร่วม
Larsenal

9
Larsenal: แต่ StringBuilder.Append (Int32) ภายในจะเรียก ToString เป็นจำนวนเต็มอยู่ดี StringBuilder ไม่สามารถหลีกเลี่ยงค่าใช้จ่ายในการจัดสรรสตริงสำหรับแต่ละองค์ประกอบได้อย่างน่าอัศจรรย์ เพียงแค่ดึงมันออกจากสายตา
itowlson

115

วิธีแก้ไขง่ายๆคือ

List<int> list = new List<int>() {1,2,3};
string.Join<int>(",", list)

ตอนนี้ฉันใช้มันในรหัสของฉันทำงาน funtastic


1
ขอบคุณ! นี่คือแนวทางที่สวยงาม
Irfan Ashraf

2
นี่เป็นแนวทางที่ดีกว่าคำตอบที่ได้รับการยอมรับ ด้วยวิธีนี้คุณไม่ต้องนำเข้า Linq และเร็วกว่า
JoKeRxbLaCk

เย็น! ฉันไม่เคยรู้จักสตริงการเข้าร่วมมีโอเวอร์โหลดทั่วไป ขอบคุณ.
ชาล


6

สำหรับวิธีแก้ปัญหาประมาณหนึ่ง gazillion สำหรับรุ่นที่ซับซ้อนกว่าเล็กน้อยของปัญหานี้ซึ่งส่วนใหญ่ทำงานช้ามีปัญหาหรือไม่ได้รวบรวม - ดูความคิดเห็นในบทความของฉันในหัวข้อนี้:

http://blogs.msdn.com/ericlippert/archive/2009/04/15/comma-quibbling.aspx

และคำอธิบาย StackOverflow:

ความท้าทายของ Eric Lippert "comma-quibbling" คำตอบที่ดีที่สุด?


ขอบคุณสำหรับลิงค์ ปัญหาการต่อสายอักขระนี้มีความซับซ้อนและมีการศึกษามากกว่าที่ฉันคาดไว้!
Steven Sudit

4

เพื่อความเจ๋งเป็นพิเศษฉันจะทำให้เป็นวิธีการขยายบน IEnumerable <T> เพื่อให้มันทำงานบน IEnumerable:

public static class IEnumerableExtensions {
  public static string BuildString<T>(this IEnumerable<T> self, string delim = ",") {
    return string.Join(delim, self)        
  }
}

ใช้มันดังนี้:

List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(list.BuildString(", "));

การเพิ่มประสิทธิภาพที่เป็นไปได้สองแบบ: 1) เพิ่มตัวคั่นหลังจากแต่ละรายการโดยไม่คำนึงถึงจากนั้นลบรายการพิเศษออกหลังจากสิ้นสุดการวนซ้ำ 2) ระบุความจุสำหรับ StringBuilder
Steven Sudit

1
หากคุณขุดตัวสะท้อนแสงออกมาปรากฎว่า Join จะสรุปความยาวเพื่อคำนวณขนาดบัฟเฟอร์ล่วงหน้าและยัง "primes the pump" ด้วยการต่อท้ายสตริงแรกนอกลูปจากนั้นภายในลูปโดยไม่มีเงื่อนไขต่อท้ายตัวคั่นหน้า สตริงถัดไป เมื่อรวมกับเทคนิคบางอย่างที่ไม่ปลอดภัย / ภายในควรเร็วมาก
Steven Sudit

@ สตีเวน: ทำตามคำแนะนำของคุณ
cdiggins

1
คุณฮาร์ดโค้ดตัวคั่นในส่วนขยายของคุณและไม่สนใจค่าที่ส่งผ่านสำหรับตัวคั่นและพลาดอัฒภาค มันควรจะเป็นreturn string.Join(delim, self);
Andrew

1

ดูเหมือนเร็วพอสมควร

IList<int> listItem = Enumerable.Range(0, 100000).ToList();
var result = listItem.Aggregate<int, StringBuilder, string>(new StringBuilder(), (strBuild, intVal) => { strBuild.Append(intVal); strBuild.Append(","); return strBuild; }, (strBuild) => strBuild.ToString(0, strBuild.Length - 1));

1

รายการ "ฉลาด" ของฉัน:

        List<int> list = new List<int> { 1, 2, 3 };
        StringBuilder sb = new StringBuilder();
        var y = list.Skip(1).Aggregate(sb.Append(x.ToString()),
                    (sb1, x) =>  sb1.AppendFormat(",{0}",x));

        // A lot of mess to remove initial comma
        Console.WriteLine(y.ToString().Substring(1,y.Length - 1));

ยังไม่ทราบวิธีเพิ่มลูกน้ำแบบมีเงื่อนไข


1
โปรดอย่าเขียนSelectโดยมีผลข้างเคียงใน lambda ในกรณีนี้คุณไม่ได้ใช้ด้วยซ้ำyดังนั้นโดยพื้นฐานแล้วคุณจึงSelectเป็นเพียง a foreach- ดังนั้นจงเขียนให้เป็นเช่นนั้น
Pavel Minaev

ฉันไม่ได้แนะนำว่านี่เป็นทางออกที่ดี OP ต้องการสิ่งที่น่าสนใจมากกว่า foreach
Larsenal

ใช่ แต่การเหยียดหยามSelectเมื่อforeachผ่านไปแล้ว "น่าสนใจ" และเป็น "การละเมิด" วิธีการที่น่าสนใจเพิ่มเติมได้ที่นี่จะใช้Enumerable.AggregateกับStringBuilderเป็นค่าเมล็ดพันธุ์ - ลองที่
Pavel Minaev

ความคิดที่ดี. ฉันต้องก้าวออกไป แต่ฉันอาจจะหมุนวน
Larsenal

0

คุณสามารถใช้ไลบรารี System.Linq; มีประสิทธิภาพมากขึ้น:

using System.Linq;
string str =string.Join(",", MyList.Select(x => x.NombreAtributo));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.