2016-04-01 2 views
-1

Ich habe das folgende Problem: Ich möchte Arbeiter Daten aus einer Textdatei lesen, die formatiert ist; worker_id;name;surname;login;. Und dann schreibe es in eine andere Datei, die nur Zeilen ohne doppelte Logins enthält.Sortieren nach Eigenschaft mit Lambdas ohne Erstellen von Klasse

Wenn ich class worker , List<workers> erstellen und versuchen, diesen Code:

List<worker> unics = workers 
      .GroupBy(w => w.login) 
      .Select(g => g.First()) 
      .ToList(); 

Wo String login = line1.Split(';')[3];, alles in Ordnung ist.

Aber wenn ich Lambdas benutze, ohne Klassenarbeiter zu erstellen (was im Moment NICHT notwendig ist), funktioniert es nicht.

List<string> unicsL = list1   //list1 - list of all lines1 in file  
      .GroupBy(x => x.Split(';')[3]) //ERROR - NullReferenceException // - Use new keyword to create object instance... 
      .Select(g => g.First())   
      .ToList(); 

Was ist das Problem?

+4

Zeigen Sie, wie 'list1' und' Arbeiter 'sind bevölkert. Alles was wir wissen sind einige "IEnumerable". Oder überprüfen Sie einfach selbst: [click] (http://stackoverflow.com/q/4660142/1997232). – Sinatr

+0

Irgendwelche Leerzeilen? oder irgendwelche Zeilen, die nicht alle 3 '; –

+0

Die Zeilen sind in beiden Fällen gleich: Wenn Sie einen Klassenarbeiter erstellen, der sie verwendet, ist alles in Ordnung, aber wenn Sie versuchen, "richtige Zeilen" zu finden, funktioniert das nicht: ich weiß nicht, wie ich dieses Lambda erstellen soll. – Jack

Antwort

0

Verwenden Sie dies.

List<string> unicsL = list1   //list1 - list of all lines1 in file  
      .Where(x=>!string.IsNullOrEmpty(x)) 
      .GroupBy(x => new {key = x.Split(';')[3]}) 
      .Select(g => g.First())   
      .ToList(); 
+0

.GroupBy (x => neu {x.Split (';') [3]}) - funktioniert immer noch nicht: Ungültige anonyme Typ-Member-Deklaration. – Jack

+0

@Jack Jedes Problem? Ich sehe deinen Kommentar, aber es scheint, dass Inhalte fehlen. –

+0

Schlägt immer noch fehl, wenn 'x' null ist –

1

Sie erhalten einen NULL-Verweis, weil xnull ist - also einer Ihrer Einträge in list1null ist.

Sie können dies überprüfen, bevor Sie Gruppe:

 List<string> unicsLx = list 
      .Where(x=> x != null) 
      .GroupBy(x => x.Split(';')[3]) 
      .Select(g => g.First())   
      .ToList(); 

Eine bessere Option wäre IsNullOrWhiteSpace() zu verwenden:

 List<string> unicsLx = list 
      .Where(x=> !string.IsNullOrWhiteSpace(x)) 
      .GroupBy(x => x.Split(';')[3]) 
      .Select(g => g.First())   
      .ToList(); 

aber Sie werden schnell ein weiteres Problem bekommen, wo es nicht 3x ; (oder die letzte ist leer), so dass Sie auch, dass der Check hinzufügen:

 .Where(x => !string.IsNullOrWhiteSpace(x) && x.Split(';').Length > 2 && !string.IsNullOrWhiteSpace(x.Split(';')[3])) 

Dies bedeutet jedoch, Sie die Split mehrfach anwenden möchten (zweimal hier und wieder auf die Gruppe), so dass man durch Zugabe eines Select eine davon entfernen können:

// Example data 
    var list = new[] { "a;b;c;d", null, "w;x;y;z;", "m;m;m;d", "", "one;two", "empty;empty;empty;" }; 

    List<string> unicsL = list 
     .Where(x => !string.IsNullOrWhiteSpace(x) && x.Split(';').Length > 2) 
     .Select(x => x.Split(';')[3]) 
     .Where(x => !string.IsNullOrWhiteSpace(x)) 
     .GroupBy(x => x) 
     .Select(g => g.First()) 
     .ToList(); 
+0

YES: .Where (x =>! String.IsNullOrWhiteSpace (x)) - Dies löste mein Problem :) Ich fand Das Problem war "irgendwo in Datei". Obwohl es eine einfache Textdatei war, wurde sie von der ReadLine() Methode gelesen. Aber als ich myList.Add ("etwas; etwas; ....) - 'manuell' verwendet habe, ist alles in Ordnung gegangen. Nachdem du deine: .Where ... Klausel hinzugefügt hast, ist dieser FEHLER verschwunden. Also DANKE SEHR VIEL :) – Jack

+0

@ freedom-m, haben immer noch einen doppelten Split auf den meisten Zeilen.Sie können auch nach Ihrer wo, wählen Sie eine Aufteilung, dann wo für die Länge und Null-oder-Whitespace, dann wählen Sie die vierte Option (3. Index). '.Where (x =>! String.IsNullOrWhiteSpace (x)) .Wählen Sie (x => x.Split (';')). Wobei (x => x.Länge> 2 &&! String.IsNullOrWhiteSpace (x [ 3])). Wählen Sie (x => x [3]) ' – Kolky

+0

@Kolky Einverstanden - es ist erwähnenswert, dass es noch zwei Splits in diesem Code geben wird. Ob es die zusätzliche Komplikation oder den Treffer wert ist, hängt davon ab, wie viele Zeilen es Zeitanforderungen gibt (zB muss es so schnell wie möglich gemacht werden), in welchem ​​Fall es wahrscheinlich bessere Möglichkeiten gibt, dies zu handhaben als mit "GroupBy". –