BestPractice - Bir dizenin ilk karakterini küçük harfe dönüştür


136

Bir dizenin ilk karakterini küçük harfe dönüştüren bir yöntem istiyorum.

Yaklaşımlarım:

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

Yaklaşımınız ne olurdu?

Yanıtlar:


240

Basit birleştirme kullanırdım:

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

İlk çözüm optimize edilmemiştir çünkü string.Formatyavaştır ve asla değişmeyecek bir formatınız varsa buna ihtiyacınız yoktur. Ayrıca, mektubu küçük harfe dönüştürmek için ekstra bir dize oluşturur, bu da gerekli değildir.

"+ 32" ile yaklaşım, ASCII karakter değeri ofsetleri hakkında bilgi gerektirdiğinden çirkin / sürdürülemez. Ayrıca Unicode verileri ve ASCII sembol karakterleriyle yanlış çıktı oluşturur.


4
char.ToLower(name[0]).ToString() + name.Substring(1)
Andrey

7
@Rookian: +çok sayıda dizeyi birleştirdiğinizde operatör yavaştır. Bu durumda a StringBuilderçok daha iyi performans gösterirdi. Ancak, +çok daha hızlı string.Format. Bir şeyi biçimlendirmeniz gerektiğinde ikincisini kullanın (tamsayıları, çiftleri veya tarihleri ​​görüntüleme gibi).
Dirk Vollmar

6
@ 0x03: Çok sayıda diziyi yinelemeli olarak birleştiriyorsanız yavaş olur. Hepsini tek bir işlemde birleştirirseniz, +operatör hiç yavaş olmaz, çünkü derleyici onu bir dönüştürür String.Concat(ancak aptalca bir nedenden String.Joindaha hızlıdır String.Concat).
Thorarin

2
Daha hızlı bir yöntem şudur: public static string ToFirstLetterLower (string text) {var charArray = text.ToCharArray (); charArray [0] = char.ToLower (charArray [0]); yeni dize döndür (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'nin yorumuna dayanarak uzantı kullandım .
KregHEk

64

Duruma bağlı olarak, biraz savunma amaçlı programlama istenebilir:

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

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

ifAçıklamada ayrıca yine değişti olacak değilse inşa ediliyor yeni bir dize engeller. Bunun yerine yöntemin null girdide başarısız olmasını ve bir ArgumentNullException.

İnsanların belirttiği gibi, bunun için kullanmak String.Formataşırıdır.


Yanılıyorsam beni düzeltin ama str.Substring (1), bu yöntemin sayımı belirtilmediğinden sembolü 1. konuma döndürecektir. böylece küçük harfte char [0] + 1 konumunda karaktere sahip olacaksınız. Bu yüzden dizede ilk karakterden başlayarak bir karakter çıkarmayı tercih ettim. Sonuç, ilk harfi olmayan dizedir. Sonra küçük harfe dönüştürülür ilk char bu dize ekleyeceğim
fedotoves

3
@ B-Rain: kendinizi düzelttiğinizi düşünün: msdn.microsoft.com/en-us/library/hxthx5h6%28VS.90%29.aspx
Thorarin

7

Her ne olursa olsun, bu cevap karşısında rastlayan herkese yardımcı olur.

Bu bir uzantı yöntemi olarak en iyi olacağını düşünüyorum, o zaman bunu yourString.FirstCharacterToLower () ile çağırabilirsiniz;

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

Benimki

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

3
Merak ediyorum, neden val.Remove? Bana karşı biraz sezgisel görünüyor.
Thorarin

@Thorarin, ilk karakteri kaldırmak istediğiniz için belli (çünkü öndeki küçük harf versiyonunu ekliyorsunuz)
Riki

2

Kabul edilen cevabı beğendim, ancak kontrol etmenin yanı sıra kısaltma ile uğraşıyorsanız string.IsNullOrEmptyda kontrol Char.IsLower(name[1])ederim. Örneğin, "AIDS" in "aIDS" olmasını istemezsiniz.


8
IMO bu arayanın sorumluluğundadır
on

1

C # kötüye kullanmadan bildiğim en hızlı çözüm:

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

Birkaçını birleştirdi ve zincirlenebilir bir uzantı yaptı. Boşlukta ve harfsizde kısa devre eklendi.

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

Bu, en son sözdizimini ve doğru doğrulamaları kullanan küçük bir uzantı yöntemidir

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
Bir istisna atmanın en iyi çözüm olup olmayacağından emin değilim. Dize boş veya boşsa, boş veya boş dizeyi döndürmeniz yeterlidir.
R. de Veen

Dize null veya boşsa, küçük harfle değiştirilecek ilk karakter olmadığı için işlem mantıklı değildir.
Carlos Muñoz

0

Bunu kullan:

string newName= name[0].ToString().ToLower() + name.Substring(1);

-3

Biçimin veri değiştirmek olmadığını ve sadece birleştirme istendiğini bilmek, kullanmaktan String.Concatdaha iyidir String.Format.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.