2009-03-06 1 views
1

Ich arbeite an einem Problem in C# 2.0/.NET 2.0, wo ich eine Sortedlist habe und alle "Werte" (nicht die "Schlüssel") dieser SortedList nach einem bestimmten suchen will substring und count up wie viele Vorkommen es gibt.Wie führe ich eine FindAll() auf einer IList <T>? (zB SortedList.Values)

Das ist, was ich versuche zu tun:

{ 
    Sortedlist<string,string> mySortedList; 
    // some code that instantiates mySortedList and populates it with data 
    List<string> myValues = mySortedList.Values; // <== does not work 
    int namesFound = myValues.FindAll(ByName(someName)).Count; 
} 

Natürlich ist dies nicht funktioniert, weil mySortedList.Values ​​eine IList zurück, während „MyValues“ eine Liste ist. Ich habe versucht, den IList so zu "casten", dass er von myValues ​​akzeptiert wird, aber es scheint nicht zu funktionieren.

Natürlich kann ich MySortedList.Values ​​in einer "foreach" -Schleife Schleife, aber ich möchte das nicht wirklich tun.

Hat jemand irgendwelche Vorschläge?

EDIT-1: Ok, nun, es sieht so aus, als gäbe es keine native Möglichkeit, dies einfach zu machen. Ich hatte angenommen, dass ich gerade etwas vermisste, aber anscheinend nicht. Ich denke, ich mache einfach eine "foreach" über die IList.

Danke für das Feedback jeder! Ich habe alle zu 1 gewählt, weil ich dachte, dass das Feedback gut ist. Danke noch einmal! :-)

EDIT-2: Sieht so aus, als hätte CMS die Antwort, nach der ich gesucht habe. Der einzige Nachteil dabei ist (wie Qwertie unterstrichen hat), dass es eine mögliche Leistungseinbuße geben kann, da es darin besteht, alle Werte in eine andere Liste zu kopieren und dann diese Liste von Anfang bis Ende zu durchsuchen. Für kurze Listen ist diese Antwort effektiv. Längere Listen? Nun, das liegt an dir zu entscheiden ...

Antwort

2

Da die IList Interface Geräte IEnumerable, können Sie tatsächlich eine List<T> von Werten erhalten mit der List<T> (IEnumerable) Constructor:

List<string> myValues = new List<string>(mySortedList.Values); 
+0

Ahh, danke! Ich sah etwas. Ich hatte nicht bemerkt, dass IList IEnumerable implementiert. Wenn ich jetzt darüber nachdenke, ergibt das vollkommenen Sinn, aber es ist mir zu dieser Zeit gar nicht in den Sinn gekommen. Das ist die Antwort! Danke CMS! :-) – Pretzel

+3

Bei dieser Lösung sollten die Auswirkungen auf die Leistung beim Kopieren der gesamten Liste berücksichtigt werden. – Qwertie

+0

Scheint mir wie die Möglichkeit, dass dies ein Leistungsproblem ist das kleine Refactoring auf eine andere Methode nicht wert. Erstellen Sie ein neues, möglicherweise großes Objekt, nur um eine einfache Methode aufzurufen? Etwas riechen dort ... – codekaizen

1

Schade, dass Sie in .Net 2.0 sind. Genau dafür ist LINQ. ;)

Sie können dies nicht wirklich tun, da FindAll() ein Mitglied von List ist. Sie könnten eine neue Liste auf den mySortedList.Values ​​erstellen, aber es scheint eine Verschwendung zu sein, da ein neues Objekt und ein darunter liegendes Array nur zugewiesen werden müssen, um eine Funktion aufzurufen.

Ich würde nur eine Dienstprogrammfunktion in einer Klasse für Listen namens FindAll() schreiben und dann Ihre IList und delegieren.

1
static void Main(string[] args) 
    { 
     string someName = "two"; 
     SortedList<string, string> mySortedList = new SortedList<string,string>() 
     { 
      {"key1", "This is key one"}, 
      {"key2", "This is key two"}, 
      {"key3", "This is key three"}, 
     }; 

     int namesFound = mySortedList.Values.Where(i => i.Contains(someName)).Count(); 
     Console.WriteLine(namesFound); 
     Console.ReadKey(); 
    } 

In Framework 2.0, vielleicht kann dies tun:

static void Main(string[] args) 
    { 
     string someName = "two"; 
     SortedList<string, string> mySortedList = new SortedList<string,string>() 
     { 
      {"key1", "This is key one"}, 
      {"key2", "This is key two"}, 
      {"key3", "This is key three"}, 
     }; 

     int namesFound = FindAll(mySortedList.Values, someName).Count ; 
     Console.WriteLine(namesFound); 
     Console.ReadKey(); 
    } 
    public static IList<String> FindAll(IList<String> items, string item) 
    { 
     List<String> result = new List<string>(); 
     foreach (String s in items) 
     { 
      if (s.Contains(item)) 
      { 
       result.Add(s); 
      } 
     } 
     return result; 
    } 

Aber das ist, was Sie wirklich nicht tun wollte.

+0

Plakat sagte sie .NET wurden 2,0 –

+0

Hoppla. habe ich vermisst. Entschuldigung, Plakat. – Bill

+0

Ich denke, du meintest "öffentliche statische Liste " (anstatt eine andere IList ), aber ich wusste, was du meintest. Netter Code. Ich gebe Ihnen das Lösungs-Häkchen ... :-) – Pretzel

1

Haben Sie schon versucht SortedListGetValueList? Dadurch erhalten Sie eine IList Werte zurück.

+0

Leider 'GetValueList; ist keine Eigenschaft der generischen Version von SortedList . –

1

Sie können nicht die Werte Eigenschaft werfen <String> zur Liste, weil es nicht eine Liste <String> --es ist ein Wörterbuch < TKey, TValue > .ValueCollection.

Aber wenn Sie LinqBridge (für .NET Framework 2.0 mit C# 3.0) verwenden, dieses Problem leicht mit LINQ wird wie folgt gelöst:

SortedList<string, string> m = ...; 
int namesFound = m.Values.Where(v => v.Contains("substring")).Count(); 

(wenn Sie noch auf C# 2.0, können Sie Poor-man's LINQ stattdessen verwenden, mit etwas mehr Arbeit)

Verwandte Themen