ลบอักขระสุดท้ายของสตริง


259

ฉันกำลังดึงข้อมูลจำนวนมากในรายการเชื่อมโยงกับฐานข้อมูลและฉันต้องการสร้างกลุ่มสตริงสำหรับผู้ที่เชื่อมต่อกับเว็บไซต์

ฉันใช้สิ่งนี้เพื่อทดสอบ แต่สิ่งนี้ไม่ใช่แบบไดนามิกดังนั้นจึงเป็นเรื่องที่แย่มาก:

string strgroupids = "6";

ฉันต้องการใช้ตอนนี้ แต่สตริงที่ส่งกลับเป็นสิ่งที่ต้องการ1,2,3,4,5,

groupIds.ForEach((g) =>
{
    strgroupids = strgroupids  + g.ToString() + ",";
    strgroupids.TrimEnd(',');
});

strgroupids.TrimEnd(new char[] { ',' });

ฉันต้องการลบ,หลังจากนี้5แต่มันไม่ทำงานแน่นอน


9
การแก้ปัญหาโดยตรงคือstrgroupids = strgroupids.TrimEnd(new char[] { ',' });แต่มีแนวคิดที่ดีกว่าด้านล่าง
Henk Holterman

คำตอบ:


613
strgroupids = strgroupids.Remove(strgroupids.Length - 1);

MSDN:

String.Remove (Int32):

ลบอักขระทั้งหมดจากสตริงนี้เริ่มต้นที่ตำแหน่งที่ระบุและดำเนินการต่อจนถึงตำแหน่งสุดท้าย


1
สมบูรณ์แบบเพื่อลบอักขระตัวสุดท้ายหากคุณต้องการลบตัวอักษรตัวสุดท้าย สำหรับคำถามของ OP ปัญหาไม่ควรเกิดขึ้นถ้าคุณไม่สร้างตัวอักษรท้าย ตรวจสอบวิธีการแก้ปัญหา @ ØyvindBråthenหากคุณอยู่ในเรือของ OP
aloisdg กำลังย้ายไปยัง codidact.com

86

ทำอย่างไรกับวิธีนี้

strgroupids = string.Join( ",", groupIds );

มากทำความสะอาด

มันจะผนวกองค์ประกอบทั้งหมดภายในgroupIdsด้วย','ระหว่างกัน แต่จะไม่ใส่','ท้าย


4
เฉพาะใน C # 4.0 ใน C # 3.5 คุณจะต้องแปลง groupIds เป็นอาร์เรย์
xanatos

3
อันนี้จะแก้ไขปัญหา OP
aloisdg กำลังย้ายไปยัง codidact.com

29

สตริงใน c # ไม่เปลี่ยนรูป เมื่ออยู่ในรหัสของคุณที่คุณทำstrgroupids.TrimEnd(',');หรือสตริงไม่ได้แก้ไขstrgroupids.TrimEnd(new char[] { ',' });strgroupids

คุณต้องทำอะไรซักอย่างstrgroupids = strgroupids.TrimEnd(',');แทน

อ้างจากที่นี่ :

สตริงไม่สามารถเปลี่ยนแปลงได้ - เนื้อหาของสตริงวัตถุไม่สามารถเปลี่ยนแปลงได้หลังจากที่สร้างวัตถุแม้ว่าไวยากรณ์จะทำให้ปรากฏขึ้นราวกับว่าคุณสามารถทำได้ ตัวอย่างเช่นเมื่อคุณเขียนรหัสนี้คอมไพเลอร์จะสร้างวัตถุสตริงใหม่เพื่อเก็บลำดับอักขระใหม่และวัตถุใหม่นั้นจะถูกกำหนดให้เป็น b สตริง "h" จะมีสิทธิ์ใช้งานการรวบรวมขยะ


11

เพิ่มวิธีการขยาย

public static string RemoveLast(this string text, string character)
{
    if(text.Length < 1) return text;
    return text.Remove(text.ToString().LastIndexOf(character), character.Length);
}

จากนั้นใช้:

yourString.RemoveLast(",");

แนวคิดพื้นฐานของการสร้างวิธีการต่อเติมนั้นดี อย่างไรก็ตาม IMHO วิธีที่ใช้ในที่นี้คือ overkill สำหรับการใช้งานนี้ OP รู้ว่าตัวละครที่เขาต้องการนั้นอยู่ที่ท้ายสตริงดังนั้นจึงไม่มีเหตุผลที่จะต้องเสียค่าใช้จ่ายในการค้นหาสตริงนั้นผ่าน LastIndexOf เพียงใช้คำตอบที่ยอมรับและทำให้เป็นวิธีการขยาย หรือพูดคำตอบทั่วไปโดยint nการป้อนจำนวนอักขระที่จะลบที่ส่วนท้าย ประการที่สองคุณทดสอบความยาวศูนย์ แต่ไม่ได้กำจัดข้อยกเว้นที่เป็นไปได้ทั้งหมด จะดีกว่าที่จะทำแล้วint index = ..LastIndexOf.. if (index >= 0)
ToolmakerSteve

ประการที่สามพารามิเตอร์string characterมีชื่อไม่ดี ข้อที่สี่ไม่ชัดเจนนักกับโปรแกรมเมอร์ในอนาคตว่านี่คือการลบอักขระที่ส่วนท้ายของสตริง โอ้รอไม่จำเป็นต้องทำเช่นนั้น มันกำลังค้นหาสตริง มันอาจถูกลบออกจากที่อื่นที่อยู่ตรงกลาง ตอนนี้โปรแกรมเมอร์บำรุงรักษาต้องตรวจสอบการใช้งานของวิธีการทั้งหมดเพื่อดูว่าพยายามทำอะไรให้สำเร็จ ไม่ใช่วิธีที่ดีในการโทรสำหรับความต้องการง่ายๆในการลบออกจากปลายสาย ขออภัยในการวิจารณ์ทั้งหมด; ฉันทำเช่นนั้นสำหรับทุกคนที่ใช้วิธีนี้ดังนั้นพวกเขาจึงเข้าใจ
ToolmakerSteve

ประการที่ห้าในบริบทของคำถามString.TrimEndจะเหมาะสมกว่าที่จะใช้ แต่เดี๋ยวก่อนมีอยู่แล้ว - และถูกกล่าวถึงในคำถามเดิมและคำตอบอื่น ๆ อีกหลายปีที่ผ่านมา - ไม่จำเป็นต้องคิดค้นวิธีการใหม่! ประโยชน์ของวิธีการของคุณคืออะไร?
ToolmakerSteve

7

ลบเครื่องหมายจุลภาคต่อท้าย:

while (strgroupids.EndsWith(","))
    strgroupids = strgroupids.Substring(0, strgroupids.Length - 1);

นี่คือย้อนหลังแม้ว่าคุณเขียนรหัสที่เพิ่มเครื่องหมายจุลภาคในสถานที่แรก คุณควรใช้string.Join(",",g)แทนสมมติว่าเป็นg string[]ให้ชื่อที่ดีกว่าgด้วย!


4

เป็นอีกทางเลือกหนึ่งในการเพิ่มเครื่องหมายจุลภาคสำหรับแต่ละรายการคุณสามารถใช้ String.Join:

var strgroupids = String.Join(",",  groupIds);

สิ่งนี้จะเพิ่มตัวคั่น ("," ในตัวอย่างนี้) ระหว่างแต่ละองค์ประกอบในอาร์เรย์


3
string strgroupids = string.Empty;

groupIds.ForEach(g =>
{
    strgroupids = strgroupids + g.ToString() + ",";
});

strgroupids = strgroupids.Substring(0, strgroupids.Length - 1);

โปรดทราบว่าForEachโดยปกติแล้วการใช้ที่นี่จะถือว่า "ผิด" (อ่านเช่นhttp://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx )

ใช้ LINQ บางส่วน:

string strgroupids = groupIds.Aggregate(string.Empty, (p, q) => p + q + ',');
strgroupids = strgroupids.Substring(0, str1.Length - 1);

ไม่มีจุดสิ้นสุดย่อย:

string strgroupids = groupIds.Aggregate(string.Empty, (p, q) => (p != string.Empty ? p + "," + q : q.ToString()));

1
@ KierenJohnstone string.Joinนั้นสมบูรณ์แบบถ้าคุณมีสตริงเป็นแหล่งหรือคุณมี C # 4.0
xanatos

3

เพิ่มเติมเพื่อแก้ปัญหาของ sll: จะดีกว่าในการตัดสตริงในกรณีที่มีบางช่องว่างในตอนท้าย

strgroupids = strgroupids.Remove(strgroupids.Trim().Length - 1);

2

string.Joinจะดีกว่า แต่ถ้าคุณจริงๆต้องการ LINQ ForEach:

var strgroupids = string.Empty;

groupIds.ForEach(g =>
{
    if(strgroupids != string.Empty){
        strgroupids += ",";
    }

    strgroupids += g;
});

หมายเหตุบางส่วน:

  • string.Joinและforeachทั้งคู่ก็ดีกว่าอย่างนี้ช้ากว่าอย่างมาก
  • ไม่จำเป็นต้องลบไฟล์ล่าสุด,เนื่องจากไม่ได้ต่อท้าย
  • ตัวดำเนินการเพิ่ม ( +=) เหมาะสำหรับการต่อท้ายสตริง
  • .ToString() ไม่จำเป็นเนื่องจากจะถูกเรียกโดยอัตโนมัติเมื่อทำการต่อเชื่อมสตริงที่ไม่ใช่
  • เมื่อจัดการกับสตริงขนาดใหญ่StringBuilderควรได้รับการพิจารณาแทนการต่อสตริง

1
BUG - ต้องกลับรายการ if test - ควรเป็นif(strgroupids != string.Empty){
ToolmakerSteve

แต่ขอขอบคุณที่เพิ่มคำตอบที่แสดงวิธีใช้สำหรับแต่ละคนในการสร้างสตริงโดยไม่ต้องการ "," ที่ท้าย! โปรดทราบว่าไม่จำเป็นต้องสร้างแลมบ์ดาและForEach; foreach (var g in groupIds) {ทำงานได้ดีเช่นกัน :)
ToolmakerSteve

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