BestPractice - แปลงอักขระตัวแรกของสตริงเป็นตัวพิมพ์เล็ก


136

ฉันต้องการวิธีที่เปลี่ยนอักขระตัวแรกของสตริงเป็นตัวพิมพ์เล็ก

แนวทางของฉัน:

1.

public static string ReplaceFirstCharacterToLowerVariant(string name)
{
    return String.Format("{0}{1}", name.First().ToString().ToLowerInvariant(), name.Substring(1));
}

2.

public static IEnumerable<char> FirstLetterToLowerCase(string value)
{
    var firstChar = (byte)value.First();
    return string.Format("{0}{1}", (char)(firstChar + 32), value.Substring(1));
}

แนวทางของคุณคืออะไร?

คำตอบ:


240

ฉันจะใช้การเรียงต่อกันง่ายๆ:

Char.ToLowerInvariant(name[0]) + name.Substring(1)

โซลูชันแรกไม่ได้รับการปรับให้เหมาะสมเนื่องจากทำงานstring.Formatช้าและคุณไม่จำเป็นต้องใช้หากคุณมีรูปแบบที่ไม่มีวันเปลี่ยนแปลง นอกจากนี้ยังสร้างสตริงพิเศษเพื่อปกปิดตัวอักษรเป็นตัวพิมพ์เล็กซึ่งไม่จำเป็น

แนวทางที่มี "+ 32" นั้นน่าเกลียด / ไม่สามารถบำรุงรักษาได้เนื่องจากต้องใช้ความรู้เกี่ยวกับการชดเชยค่าอักขระ ASCII นอกจากนี้ยังสร้างเอาต์พุตที่ไม่ถูกต้องด้วยข้อมูล Unicode และอักขระสัญลักษณ์ ASCII


4
ฉันจะทำ:char.ToLower(name[0]).ToString() + name.Substring(1)
Andrey

7
@Rookian: ตัว+ดำเนินการช้าเมื่อคุณเชื่อมสตริงจำนวนมากเข้าด้วยกัน ในกรณีStringBuilderนั้นจะทำงานได้ดีกว่ามาก อย่างไรก็ตาม+เร็วกว่าstring.Formatมาก ใช้อย่างหลังเมื่อคุณต้องการจัดรูปแบบบางอย่าง (เช่นการแสดงจำนวนเต็มคู่หรือวันที่)
Dirk Vollmar

6
@ 0x03: จะช้าก็ต่อเมื่อคุณเชื่อมต่อสตริงจำนวนมากซ้ำ ๆ หากคุณเชื่อมต่อทั้งหมดเข้าด้วยกันในการดำเนินการเดียวตัวดำเนิน+การจะไม่ช้าเลยเพราะคอมไพเลอร์เปลี่ยนเป็น a String.Concat(แต่String.Joinเร็วกว่าString.Concatด้วยเหตุผลโง่ ๆ )
Thorarin

2
วิธีที่เร็วกว่านี้คือสตริงแบบคงที่สาธารณะ ToFirstLetterLower (ข้อความสตริง) {var charArray = text ToCharArray (); charArray [0] = ถ่าน. ToLower (charArray [0]); ส่งคืนสตริงใหม่ (charArray); }
Matteo Migliore

2
ฉันใช้ส่วนขยาย public static string ToLowerFirst(this string source) { if (string.IsNullOrWhiteSpace(source)) return source; var charArray = source.ToCharArray(); charArray[0] = char.ToLower(charArray[0]); return new string(charArray); } ตามความคิดเห็นของ @ MatteoMigliore
KregHEk

64

การเขียนโปรแกรมป้องกันเล็กน้อยอาจเป็นที่ต้องการทั้งนี้ขึ้นอยู่กับสถานการณ์:

public static string FirstCharacterToLower(string str)
{
    if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
        return str;

    return Char.ToLowerInvariant(str[0]) + str.Substring(1);
}

ifคำสั่งยังช่วยป้องกันสตริงใหม่จากถูกสร้างขึ้นถ้ามันไม่ได้ไปจะมีการเปลี่ยนแปลงอยู่แล้ว คุณอาจต้องการให้เมธอดล้มเหลวในอินพุต null แทนและโยนArgumentNullExceptionไฟล์.

ดังที่ผู้คนได้กล่าวถึงการใช้String.Formatสิ่งนี้มากเกินไป


แก้ไขฉันถ้าฉันผิด แต่ str. สตริง (1) จะส่งคืนสัญลักษณ์ที่ตำแหน่ง 1 เนื่องจากไม่ได้ระบุจำนวนสำหรับวิธีนี้ ดังนั้นคุณจะมี char [0] ในตัวพิมพ์เล็ก + ตัวอักษรที่ตำแหน่ง 1 ดังนั้นฉันจึงต้องการลบหนึ่งอักขระโดยเริ่มจากอักขระแรกในสตริง ผลลัพธ์คือสตริงที่ไม่มีอักษรตัวแรก จากนั้นฉันจะเพิ่มสตริงนี้ใน char ตัวแรกที่แปลงเป็นตัวพิมพ์เล็ก
fedotoves

4
@ B-Rain: พิจารณาตัวเองว่าแก้ไขแล้ว: msdn.microsoft.com/en-us/library/hxthx5h6%28VS.90%29.aspx
Thorarin

7

ในกรณีที่มันช่วยให้ใครก็ตามที่บังเอิญเจอคำตอบนี้

ฉันคิดว่านี่น่าจะดีที่สุดในฐานะวิธีการขยายแล้วคุณสามารถเรียกมันด้วย yourString.FirstCharacterToLower ();

public static class StringExtensions
{
    public static string FirstCharacterToLower(this string str)
    {
        if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
        {
            return str;
        }

        return Char.ToLowerInvariant(str[0]) + str.Substring(1);
    }
}

3

เหมืองคือ

if (!string.IsNullOrEmpty (val) && val.Length > 0)
{
    return val[0].ToString().ToLowerInvariant() + val.Remove (0,1);   
}

3
ฉันอยากรู้ว่าทำไมval.Remove? ดูเหมือนจะสวนทางกับฉันเล็กน้อย
Thorarin

@Thorarin เห็นได้ชัดว่าคุณต้องการลบถ่านตัวแรก (เนื่องจากคุณกำลังเพิ่มรุ่นตัวพิมพ์เล็กไว้ข้างหน้า)
Riki

2

ฉันชอบคำตอบที่ได้รับการยอมรับ แต่นอกจากการตรวจสอบstring.IsNullOrEmptyแล้วฉันจะตรวจสอบด้วยว่าChar.IsLower(name[1])ในกรณีที่คุณกำลังจัดการกับตัวย่อ เช่นคุณคงไม่อยากให้ "เอดส์" กลายเป็น "เด็ก"


8
IMO นี่เป็นความรับผิดชอบของผู้โทร
เมื่อ

1

วิธีแก้ปัญหาที่เร็วที่สุดที่ฉันรู้โดยไม่ใช้ c # ในทางที่ผิด:

public static string LowerCaseFirstLetter(string value)
{
    if (value?.Length > 0)
    {
        var letters = value.ToCharArray();
        letters[0] = char.ToLowerInvariant(letters[0]);
        return new string(letters);
    }
    return value;
}

0

รวมกันสองสามตัวและทำให้มันเป็นส่วนขยายแบบ chainable เพิ่มการลัดวงจรบนช่องว่างและไม่ใช่ตัวอักษร

public static string FirstLower(this string input) => 
    (!string.IsNullOrWhiteSpace(input) && input.Length > 0 
        && char.IsLetter(input[0]) && !char.IsLower(input[0]))
    ? input[0].ToString().ToLowerInvariant() + input.Remove(0, 1) : input;

0

นี่เป็นวิธีการขยายเล็กน้อยโดยใช้ไวยากรณ์ล่าสุดและการตรวจสอบที่ถูกต้อง

public static class StringExtensions
{
    public static string FirstCharToLower(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
            default: return input.First().ToString().ToLower() + input.Substring(1);
        }
    }
}

1
ไม่แน่ใจว่าการทิ้งข้อยกเว้นจะเป็นทางออกที่ดีที่สุดหรือไม่ สตริงเป็นโมฆะหรือว่างเพียงส่งคืนค่าว่างหรือสตริงว่าง
R. de Veen

หาก String เป็นโมฆะหรือว่างเปล่าการดำเนินการจะไม่สมเหตุสมผลเนื่องจากไม่มีอักขระตัวแรกที่จะเปลี่ยนเป็นตัวพิมพ์เล็ก
Carlos Muñoz


0

System.Linqหากคุณไม่ต้องการที่จะอ้างอิงสตริงของคุณสองครั้งในการแสดงออกของคุณสามารถทำเช่นนี้โดยใช้

new string("Hello World".Select((c, i) => i == 0 ? char.ToLower(c) : c).ToArray())

ด้วยวิธีนี้หากสตริงของคุณมาจากฟังก์ชันคุณไม่จำเป็นต้องเก็บผลลัพธ์ของฟังก์ชันนั้น

new string(Console.ReadLine().Select((c, i) => i == 0 ? char.ToLower(c) : c).ToArray())

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