Obține ultima duplicat element într-o listă

0

Problema

Am o lista conține elementele duplicat.

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

Am ajunge la ieșire, care este postpone, access, success prin utilizarea

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

Am văzut alt exemplu, ei pot folosi groupby pentru a obține cele mai recente element, deoarece au alt articol ca ID-ul etc. Acum am numai șir, cum pot obține cele mai recente element din listă, care este access, postpone, success? Orice sugestie?

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

Cel mai bun răspuns

2

O modalitate de a face acest lucru ar fi de a folosi Indicele de element în colecție originală, împreună cu GroupBy. De exemplu,

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

Ieșire

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

Apreciez cu frumos exemplu. Ajută atât de mult.
yancy
0

Ta lista de intrare este numai de tip string, deci folosind groupBy nu adaugă nimic. Dacă iei în considerare cod, prima linie vă oferă distincte lista, pierzi numai articole distincte pentru că ai făcut un șir de caractere.alăturați-vă de pe linia 2. Tot ce trebuie să faceți este să adăugați o linie înainte de a vă alătura:

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

Presupun că ai putea face codul mai concis pentru că ai nevoie de nici .Selectați(o => o), nici .ToArray() în apelul la string.Se alăture.

GroupBy-ar fi folosit dacă ai avut o listă de clasă/struct/înregistrare/tuplu elemente, în cazul în care ar putea să doriți să grup de o anumită cheia (sau cheile), mai degrabă decât folosind Distincte() pe toată chestia asta. GroupBy este foarte util și ar trebui să învețe că, și, de asemenea, ToDictionary și ToLookup LINQ helper funcționalitate.

2021-11-23 10:44:48
0

O OrderedDictionary face acest lucru. Tot ce trebuie să faceți este să adăugați elemente la ea cu o logica "dacă e în dicționar, scoateți-l. adauga". OrderedDictionary păstrează ordinea de adăugare, prin eliminarea mai devreme adăugat una și re-adăugarea se sare la sfârșitul dicționar

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

Dvs. d.Keys este acum o listă de siruri de caractere

access
postpone
success

OrderedDictionary este în Collections.Specialized nume

Dacă ai vrut cheile ca un fișier CSV, puteți utiliza Cast pentru a le transforma din obiect string

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

Multumesc pentru explicatie buna..... Am avut de a învăța ceva nou 'OrderedDictionary'.
yancy
0

Deci, de ce n-ar trebui să se întoarcă la prima apariție a "amâna"? Pentru că mai târziu, în secvența vezi același cuvânt "amâne" din nou. De ce ai reveni la prima apariție a "accesa"? Pentru că mai târziu, în secvența tu nu vezi acest cuvânt mai.

Deci: returna un cuvânt, dacă restul de secvență nu are acest cuvânt.

Acest lucru ar fi ușor în LINQ, cu recursivitate, dar nu este foarte eficient: pentru fiecare cuvânt ar trebui să verificați restul de secvență pentru a vedea dacă cuvântul este în repaus.

Ar fi mult mai eficient să-ți amintești cel mai mare indice pe care ai găsit un cuvânt.

Ca o metodă de prelungire. Dacă nu sunteți familiarizați cu metodele de extensie, vezi metode de extensie demistificat.

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

Deci, pentru fiecare element din sursa secvență, vom verifica dacă este în dicționar. Dacă nu, vom adăuga elementul cheie în dicționar. Valoarea indicelui.

Dacă acesta este deja în dicționar, atunci valoarea a fost cel mai mare indice de unde am găsit acest articol înainte. Se pare că indicele curent este mai mare, deci vom înlocui valoarea în dicționar.

În cele din urmă am comanda perechi de valori-cheie în dicționarul de ascendent valoare, și să se întoarcă doar tastele.

2021-11-23 21:40:54

În alte limbi

Această pagină este în alte limbi

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