Listedeki son yinelenen öğeyi alma

0

Soru

Yinelenen öğeler içeren bir listem var.

List<string> filterList = new List<string>()
{
     "postpone", "access", "success", "postpone", "success"
};

Çıktıyı alıyorum postpone, access, success kullanarak

List<string> filter = filterList.Distinct().ToList();
string a = string.Join(",", filter.Select(a => a).ToArray());
Console.WriteLine(a);

Başka bir örnek gördüm, kullanabilirler groupby kimlik vb.Gibi başka bir öğeye sahip oldukları için en son öğeyi almak için. Şimdi sadece dizeye sahibim, listedeki en son öğeyi nasıl alabilirim access, postpone, success? Herhangi bir öneri?

c# linq
2021-11-23 10:34:46
4

En iyi cevabı

2

Bunu yapmanın bir yolu, orijinal koleksiyondaki öğenin Dizinini GroupBy ile birlikte kullanmak olacaktır. Örneğin,

    var lastDistinct = filterList.Select((x,index)=> new {Value=x,Index=index})
                                 .GroupBy(x=>x.Value)
                                 .Select(x=> x.Last())
                                 .OrderBy(x=>x.Index)
                                 .Select(x=>x.Value);
    var result = string.Join(",",lastDistinct);

Çıktı

access,postpone,success
2021-11-23 10:58:27

Güzel örnekle teşekkür ederim. Çok yardımcı olduğunuz.
yancy
0

Giriş listeniz yalnızca string türündedir, bu nedenle groupBy kullanmak gerçekten hiçbir şey eklemez. Kodunuzu göz önünde bulundurursanız, ilk satırınız size dıstınct listesini verir, yalnızca dıstınct öğelerini bir dize yaptığınız için kaybedersiniz.2. hatta katılın. Tek yapmanız gereken katılmadan önce bir satır eklemek:

List<string> filter = filterList.Distinct().ToList();
string last = filter.LastOrDefault();
string a = string.Join(",", filter.Select(a => a).ToArray());
Console.WriteLine(a);

Ne gerektiğinden daha fazla kod veciz senin yapabiliriz sanırım .(A => a) nor öğesini seçin .Çağrı dizenizde ToArray ().Katılmak.

GroupBy, her şeyde Dıstınct () kullanmak yerine belirli bir anahtara (veya anahtarlara) göre gruplamak isteyebileceğiniz class/struct/record/tuple öğelerinin bir listesine sahip olsaydınız kullanılır. GroupBy çok kullanışlıdır ve bunu ve ayrıca ToDictionary ve ToLookup LINQ yardımcı işlevselliğini öğrenmelisiniz.

2021-11-23 10:44:48
0

Bunu bir OrderedDictionary yapar. Tek yapmanız gereken, öğelerinizi "sözlükte varsa, kaldırın" mantığıyla eklemektir. ekleyin". OrderedDictionary ekleme sırasını korur, böylece daha önce eklenmiş olanı kaldırır ve yeniden ekleyerek sözlüğün sonuna atlar

var d = new OrderedDictionary();
filterList.ForEach(x => { if(d.Contains(x)) d.Remove(x); d[x] = null; });

Senin d.Keys şimdi dizelerin bir listesi

access
postpone
success

OrderedDictionary içinde Collections.Specialized ad

Anahtarları CSV olarak istiyorsanız, şunları kullanabilirsiniz Cast onları nesneden dizeye çevirmek için

var s = string.Join(",", d.Keys.Cast<string>());
2021-11-23 18:59:40

Teşekkür için iyi bir açıklama..... 'OrderedDictionary' adlı yeni şeyi öğrenmiştim.
yancy
0

Öyleyse neden ilk "ertele" olayını geri getirmiyorsunuz? Çünkü daha sonra sırayla aynı kelimeyi tekrar "ertele" yi görüyorsunuz. Neden "erişim" in ilk oluşumunu döndürürsünüz? Çünkü dizinin ilerleyen bölümlerinde artık bu kelimeyi görmüyorsunuz.

Yani: dizinin geri kalanında bu sözcük yoksa bir sözcük döndürün.

Bu, özyineleme ile lınq'da kolay olurdu, ancak çok verimli değil: her kelime için, kelimenin geri kalanında olup olmadığını görmek için dizinin geri kalanını kontrol etmeniz gerekir.

Üzerinde bir kelime bulduğunuz en yüksek dizini hatırlamak çok daha verimli olacaktır.

Uzatma yöntemi olarak. Eğer sen are değil bildik ile uzatma yöntemleri, görmek uzatma yöntemleri açıklığa kavuşturdu.

private static IEnumerable<T> FindLastOccurences<T>(this IEnumerable<T> source)
{
    return FindLastOccurrences<T>(source, null);
}

private static IEnumerable<T> FindLastOccurences<T>(this IEnumerable<T> source,
    IEqualityComparer<T> comparer)
{
    // TODO: check source not null
    if (comparer == null) comparer = EqualityComparer<T>.Default;

    Dictionary<T, int> dictionary = new Dictionary<T, int>(comparer);

    int index = 0;
    foreach (T item in source)
    {
        // did we already see this T? = is this in the dictionary
        if (dictionary.TryGetValue(item, out int highestIndex))
        {
            // we already saw it at index highestIndex.
            dictionary[item] = index;
        }
        else
        {
            // it is not in the dictionary, we never saw this item.
            dictionary.Add(item, index);
        }
        ++index;
    }

    // return the keys after sorting by value (which contains the highest index)
    return dictionay.OrderBy(keyValuePair => keyValuePair.Value)
                    .Select(keyValuePair => keyValuePair.Key);
}
         

Bu nedenle, kaynak dizisindeki her öğe için sözlükte olup olmadığını kontrol ederiz. Değilse, öğeyi sözlüğe anahtar olarak ekleriz. Değer endekstir.

Zaten sözlükte bulunuyorsa, değer daha önce bu öğeyi bulduğumuz yerin en yüksek diziniydi. Görünüşe göre mevcut endeks daha yüksek, bu yüzden sözlükteki değeri değiştiriyoruz.

Son olarak, sözlükteki anahtar değer çiftlerini artan değere göre sıralarız ve yalnızca anahtarları döndürürüz.

2021-11-23 21:40:54

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................