C # dilinde dize anahtar türüyle Büyük / Küçük Harfe Duyarlı Sözlük


156

Eğer bir yöntemim varsa Dictionary<String,...>,ContainsKey küçük harfe duyarlı olmayan mü?

Bu ilgili görünüyordu, ama düzgün anlamadım: c # Sözlük: beyanları ile Key case-insensitive yapma


6
Kullanmanın nesi yanlış StringComparer.InvariantCultureIgnoreCase? Ne diyor ...
Lepi

5
Hiç duymadım, dolayısıyla soru!
Bay Boy


Bu soru ilişkilidir, ancak bunun bir kopyası değildir. Bu, mevcut bir sözlükle nasıl başa çıkılacağına girer. Yeni kodla başlıyorum, bu yüzden cevaplar daha uygun.
goodeye

Yanıtlar:


322

Bu ilgili görünüyordu, ama düzgün anlamadım: c # Sözlük: beyanları ile Key case-insensitive yapma

Gerçekten ilişkilidir. Çözüm, sözlük örneğine standart dize karşılaştırma yöntemini (büyük / küçük harfe duyarlı) değil, büyük / küçük harfe duyarlı olmayan bir yöntem kullanmasını söylemektir. Bu, uygun kurucu kullanılarak yapılır :

var dict = new Dictionary<string, YourClass>(
        StringComparer.InvariantCultureIgnoreCase);

Yapıcı IEqualityComparersözlüğe anahtarların nasıl karşılaştırılacağını söyler.

StringComparer.InvariantCultureIgnoreCaseIEqualityComparerdizeleri büyük / küçük harfe duyarlı olmayan bir şekilde karşılaştıran bir örnek verir .


1
Mükemmel, karşılaştırıcıyı ctor'a geçirmenin STL benzeri bir yolunu kaçırmıştım.
Bay Boy

7
Burada herhangi bir kodlama sorununun cevabını her zaman nasıl bulduğumu şaşırtmak asla bitmiyor! Belki senden sonraki kedimi söylerim, Konrad! :-)
Jamie

10
Mümkün, StringComparison.OrdinalIgnoreCase karşılaştırıcısı kültür tabanlı olandan daha hızlı: stackoverflow.com/questions/492799/…
Manushin Igor

Bir sözlük oluşturmuyorsam ama bir nesnenin parçası olarak aldığım varolan bir sözlükte büyük / küçük harf duyarsız bir anahtar eşleşmesi için ContainsKey () kullanmaya çalışıyorsam nasıl yapabilirim?
Shridhar R Kulkarni

1
@ShridharRKulkarni Temelde (verimli) yapamazsınız. Karşılaştırma mantığı, dahili sözlük veri yapısının temel bir parçasıdır. Buna izin vermek için, kabın verileri için birden çok endeks tutması gerekir ve sözlükler bunu yapmaz.
Konrad Rudolph

21
var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");

if (myDic.ContainsKey("hello"))
    Console.WriteLine(myDic["hello"]);

1
Kod pasajı her şeyi söylüyor. Çok yararlı. Bu gönderinin neden sadece 3 dakika geç kaldığı için kabul edilen cevaba kıyasla daha az oy verdiğinden emin değilim.
RBT

14

3. parti veya harici dll çekti sözlük ile anlaşma az şansı vardır. Linq kullanma

YourDictionary.Any(i => i.KeyName.ToLower().Contains("yourstring")))


3
Harika çalışıyor. Eğer değiştirirseniz Bir uyarı olsa Anyhiç SingleOrDefaultalmazsınız size nullo yoksa geriye, yerine anahtarı ve değer kümesi hem bir KeyValuePair alacak null!
NibblyPig

1
ContainsO zaman üzerinde çalıştığınız bir şeyin çok özel bir kullanım durumu gibi görünüyor. Daha genel bir yardımcı cevap Equalsolarak daha iyi olduğunu düşünüyorum . Ve aynı notta, bir dizeyi çoğaltmak yerine, ToLower()kullanmak daha da iyi olurdu StringComparison.xxxCase.
Suamere

1
Bu çok yararlı oldu ve ToLower kurtulmak kesinlikle bir gelişme - benim kullanım durumum: dönüş AppliedBuffs.Any (b => b.Key.Equals (Name, StringComparison.OrdinalIgnoreCase)); mükemmel bir büyük / küçük harf duyarsız Büyük / küçük harf duyarlı bir sözlük içerir.
David Burford

Bunu çok cazip buldum. Dikkatli bir kelime, eğer sözlüğün sahibi iseniz bu kesinlikle bunu yapmanın yolu değildir. Bu yaklaşımı yalnızca sözlüğün nasıl somutlaştırıldığını bilmiyorsanız kullanın. O zaman bile, dizenin tam eşleşmesi için (sadece parça eşleşmesi değil), kullanım dict.Keys.Contains("bla", appropriate comparer)kolaylığı için LINQ aşırı yükünü kullanın.
nawfal

1

Ben sadece bir ASP.NET Core denetleyicisinde bir caseINsensitive sözlük gerektiğinde aynı tür bir sorunla karşılaştı.

Hile yapan bir uzatma yöntemi yazdım. Belki bu başkaları için de yararlı olabilir ...

public static IDictionary<string, TValue> ConvertToCaseInSensitive<TValue>(this IDictionary<string, TValue> dictionary)
{
    var resultDictionary = new Dictionary<string, TValue>(StringComparer.InvariantCultureIgnoreCase);
    foreach (var (key, value) in dictionary)
    {
        resultDictionary.Add(key, value);
    }

    dictionary = resultDictionary;
    return dictionary;
}

Uzantı yöntemini kullanmak için:

myDictionary.ConvertToCaseInSensitive();

Ardından sözlükten bir değer alın:

myDictionary.ContainsKey("TheKeyWhichIsNotCaseSensitiveAnymore!");

0

Örnek oluşturmada herhangi bir denetiminiz yoksa, nesnenizin json vb. Tarafından yok edildiğini varsayalım, sözlük sınıfından miras alan bir sarmalayıcı sınıfı oluşturabilirsiniz.

public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
{
    public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase){}
}
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.