myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » doppelte Werte einer Liste löschen
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

doppelte Werte einer Liste löschen

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
myCSharp.de
Moderationshinweis von herbivore (11.08.2010 10:15):

Dies ist ein Thread, auf den aus der FAQ verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!
 
impact_1991 impact_1991 ist männlich
myCSharp.de-Mitglied

Dabei seit: 19.07.2010
Beiträge: 44
Herkunft: Eichsfeld


impact_1991 ist offline

doppelte Werte einer Liste löschen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo ich wollte alle Werte einer doppelten Liste lösche, weiß einer von euch, was ich falsch gemacht habe und wie es besser geht ?
Hab schon gegoogelt aber nichts passendes gefunden

C#-Code:
        private List<string> doppelte_finden(List<string> Liste_string)
        {
            for (int i = 0; i < Liste_string.Count; i++)
            {
                for (int j = 0; j < Liste_string.Count; j++)
                {
                    if (Liste_string[i] == Liste_string[j]) // Fehler
                    {
                        Liste_string.Remove(Liste_string[j]);
                    }
                }
            }
            return Liste_string;
        }

Gruß impact_1991
11.08.2010 07:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
a957m a957m ist männlich
myCSharp.de-Mitglied

Dabei seit: 20.05.2007
Beiträge: 254
Entwicklungsumgebung: Visual Studio 2005
Herkunft: Stuttgart


a957m ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

na was denkste was beim ersten Durchlauf passiert ?

Liste_string[0] == Liste_string[0]

Ich würde, die Elemente in einem Dictionary<string,string> sammeln. Eine foreach Schleife und bei jedem Element nachschauen, ob es schon im Dictionary enthalten ist. Das funktioniert, dann auch wenn ein Element öfter als zweimal vorkommt.

Tschüss
11.08.2010 08:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
impact_1991 impact_1991 ist männlich
myCSharp.de-Mitglied

Dabei seit: 19.07.2010
Beiträge: 44
Herkunft: Eichsfeld

Themenstarter Thema begonnen von impact_1991

impact_1991 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

danke für den Vorschlag
das müsste klappen

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von impact_1991 am 11.08.2010 10:17.

11.08.2010 08:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
tom-essen tom-essen ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2140.png


Dabei seit: 15.05.2005
Beiträge: 1.815
Entwicklungsumgebung: VS.NET 2013
Herkunft: NRW


tom-essen ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo!
Zudem sollte die Liste zwingend rückwärts durchlaufen werden, sonst fällt ein Index irgendwann ins Leere, wenn man vorher was gelöscht hat.

Also bei sowas immer

C#-Code:
for (int i = Liste_string.Count - 1; i >= 0; i--) ...
11.08.2010 08:28 Beiträge des Benutzers | zu Buddylist hinzufügen
impact_1991 impact_1991 ist männlich
myCSharp.de-Mitglied

Dabei seit: 19.07.2010
Beiträge: 44
Herkunft: Eichsfeld

Themenstarter Thema begonnen von impact_1991

impact_1991 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich hab es jetzt so umgesetzt

C#-Code:
private List<string> doppelte_finden(List<string> Liste_string)
        {
            List<string> ergebnis= new List<string>();
            bool schon_vorhanden = false;

            for (int i = 0; i < Liste_string.Count; i++)
            {
                for (int j = 0; j < ergebnis.Count; j++)
                {
                    if (Liste_string[i] == ergebnis[j])
                    {
                        schon_vorhanden = true;
                        break;

                    }

                }
                if (schon_vorhanden == false)
                {
                    ergebnis.Add(Liste_string[i]);

                }
                else
                {
                    schon_vorhanden = false;
                }
            }
            return ergebnis;
        }

fals jemand etwas übersichtlicheres oder schnelleres kennt kann es gern posten

gruß impact

EDIT von herbivore: Ungünstige Lösung wegen der quadratischen Laufzeit. Erklärung und bessere Lösungen (mit linearer Laufzeit) siehe weiter unten.
11.08.2010 08:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
xxMUROxx xxMUROxx ist männlich
myCSharp.de-Mitglied

avatar-3236.jpg


Dabei seit: 11.01.2010
Beiträge: 1.552
Entwicklungsumgebung: VS 13, SSMS 12
Herkunft: Südtirol/Italien


xxMUROxx ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo impact_1991,
aus diesem:
if(schon_vorhanden == false)
if(!schon_vorhanden)
folgt ganz schnell dies:  [Tipp] Anfängerfehler == true / == false

Gruß Michael

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von xxMUROxx am 11.08.2010 09:25.

11.08.2010 09:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
zommi zommi ist männlich
myCSharp.de-Mitglied

avatar-2617.png


Dabei seit: 14.11.2007
Beiträge: 1.361
Entwicklungsumgebung: VS 2005+2010
Herkunft: Berlin


zommi ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

Vorschlag 1:

C#-Code:
// behält die Reihenfolge bei
private static List<string> ohneDoppelte(List<string> stringList)
{
    // Menge der strings, die bereits in der Ergebnisliste sind
    HashSet<string> strings = new HashSet<string>();

    // Mittels LINQ die Werte übernehmen, die vorher noch nicht vorkamen
    return stringList.Where(x =>
        {
            // wenn schon in der ErgebnisListe, dann nicht übernehmen
            if (strings.Contains(x))
            {
                return false;
            }
            // andernfalls der Menge hinzufügen und Element übernehmen
            else
            {
                strings.Add(x);
                return true;
            }
        })
        .ToList();
}

Vorschlag 2:

C#-Code:
// ignoriert die Reihenfolge
private static List<string> ohneDoppelte(List<string> stringList)
{
    // Liste in eine Menge und wieder zurück in eine Liste umwandeln
    // (doppelte Einträge gehen verloren)
    return (new HashSet<string>(stringList)).ToList();
}

Vorschlag 3: (Annahme: RemoveAll(...) geht sequentiell in der normalen Iterationsreihenfolge durch)

C#-Code:
// behält die Reihenfolge bei
private static List<string> ohneDoppelte(List<string> stringList)
{
    // Dictionary das mitzählt, wie oft ein Element bereits vorkam
    Dictionary<string, int> stringOccurence = new Dictionary<string, int>();
    // Mit 0 initialisieren
    foreach (string s in stringList)
        stringOccurence[s] = 0;

    // Kopie erzeugen
    List<string> result = new List<string>(stringList);
    // Alle Elemente entfernen, die vorher schonmal aufgetreten sind
    // (und dabei mitzählen, dass sie aufgetreten sind)
    result.RemoveAll(x => (stringOccurence[x]++ > 0));
    return result;
}

Ah, hier wäre noch eine vierte LINQ-Variante

C#-Code:
// ignoriert die Reihenfolge
private static List<string> ohneDoppelte(List<string> stringList)
{
    return stringList.Distinct().ToList();
}

beste Grüße
zommi

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von zommi am 11.08.2010 09:46.

11.08.2010 09:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
impact_1991 impact_1991 ist männlich
myCSharp.de-Mitglied

Dabei seit: 19.07.2010
Beiträge: 44
Herkunft: Eichsfeld

Themenstarter Thema begonnen von impact_1991

impact_1991 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hy zommi,

könntest du vllt ein paar kurze kommentare dazu schreiben was du da machst?

auf jeden fall ist es sehr übersichtlich und es funktioniert.

Danke
11.08.2010 09:27 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
zommi zommi ist männlich
myCSharp.de-Mitglied

avatar-2617.png


Dabei seit: 14.11.2007
Beiträge: 1.361
Entwicklungsumgebung: VS 2005+2010
Herkunft: Berlin


zommi ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Habe oben noch Kommentare eingefügt.

Die erste beiden und die vierte Variante nutzen die LINQ-Extensions ab .NET 3.5.
Daher hab ich noch eine Variante 3 hinzugefügt, die auch mit .NET 2.0 funktionieren sollte, da sie nur das Dictionary<,> verwendet.

Die Idee ist aber bei allen, dass eine zusätzliche Hash-basierte Collection verwendet wird, der die Eigenschaft doppelte Einträge zu entfernen inhärent ist.
Dadurch, dass die hash-basierten Collections im Idealfall einen Zugriff in O(1) ermöglichen, reduziert sich in allen Fällen die Laufzeit auf O(n), im Vergleich zum O(n^2) deiner verschachtelten Schleife.

beste Grüße
zommi

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von zommi am 11.08.2010 09:37.

11.08.2010 09:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.464
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo impact_1991,

auch wenn das Löschen von Duplikaten ein besonderer Spezialfall von  [FAQ] Auflistungs-Elemente suchen und entfernen ist, der nach einem Dictionary/HashSet bzw. nach Linq schreit, sind in der FAQ doch einige Anmerkungen enthalten, die von grundsätzlichem Interesse sind.

herbivore
11.08.2010 09:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.618
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

11.08.2010 10:14 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 9 Jahre.
Der letzte Beitrag ist älter als 9 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 23.02.2020 02:19