2008-12-02 6 views
1

J'ai une foule de valeurs stockées dans une hashtable .net 2.0. Ce que je voudrais vraiment trouver est un moyen de faire une instruction SQL sur la table.Je cherche un moyen de rechercher les valeurs dans une hashtable .net en utilisant des caractères génériques

Signification, je voudrais obtenir une liste des clés dont les valeurs associées correspondre à un modèle de texte très simple (le long des lignes de « commence par un certain nombre ».)

L'objectif final sera de supprimer ces enregistrements de la table de hachage pour traitement ultérieur.

Je me bats la tête depuis un moment et je n'arrive pas à trouver quoi que ce soit.

Des idées?

(Au hasard cette question est importante: en raison des réalités de ce projet, des widgets 3ème partie ou la mise à niveau vers une version plus récente de .net sont sur la table.)

Répondre

2

Vous pouvez utiliser une expression régulière contre chaque clé de la hashtable. Ceci est très sale, mais cela fonctionne:

static void Main(string[] args) 
    { 
     Hashtable myhashtable = new Hashtable(); 
     myhashtable.Add("Teststring", "Hello"); 
     myhashtable.Add("1TestString1", "World"); 
     myhashtable.Add("2TestString2", "Test"); 

     List<String> newht = new List<String>; 

     //match all strings with a number at the front 
     Regex rx = new Regex("^[1-9]"); 
     foreach (string key in myhashtable.Keys) 
     { 
      if (rx.IsMatch(key) == true) 
      { 
       newht.Add(key); 
      } 
     } 

     //Loop through all the keys in the new collection and remove them from 
     //them from the main hashtable. 
     foreach (string key in newht) 
     { 
      myhashtable.Remove(key); 
     } 
    } 

EDIT: Et juste pour le plaisir, voici la version LINQ (désolé je viens d'avoir trop).

  Hashtable myhashtable = new Hashtable(); 
      myhashtable.Add("Teststring", "Hello"); 
      myhashtable.Add("1TestString1", "World"); 
      myhashtable.Add("2TestString2", "Test"); 

      Regex rx = new Regex("^[1-9]"); 
      var k = (from string key in myhashtable.Keys 
        where rx.IsMatch(key) 
        select key).ToList(); 

      k.ForEach(s => myhashtable.Remove(s)); 

EDIT: Je viens de la liste supplémentaire de piqûre plutôt qu'une Hashtable, je ne me souvenais version .net avait des listes génériques dans ce *** gifles front

+0

C'est ce que je suggérerais pour ses circonstances aussi. –

+0

Quand j'ai vu les questions pour la première fois, j'étais comme "Oui! LINQ time" puis j'ai vu .net 2.0 puis: '(, en utilisant à nouveau les boucles foreach lol –

+0

Ceci va être la première pièce de notre quête pour améliorer ce système à .net 3.5.;) –

3

Si vous cherchez vraiment pour les choses qui commencent par un nombre, alors vous pouvez le faire beaucoup plus rapidement qu'avec un Regex. Regardez simplement le premier caractère de chaque touche et déterminez s'il s'agit d'un chiffre. Stockez les clés que vous souhaitez supprimer dans une liste, car vous ne devez conserver que la clé.

List<string> keysToRemove = new List<string>(myhashtable.Count); 
    foreach (string key in myhashtable.Keys) 
    { 
     if (char.IsDigit(key[0]) 
     { 
      keysToRemove.Add(key); 
     } 
    } 

    foreach (string key in keysToRemove) 
    { 
     myhashtable.Remove(key); 
    } 
+0

+1. C'est vrai, mais si vous avez besoin de correspondre à tout autre chose, alors une regex avec le travail. –

+0

@Nathan. D'accord. Regex est une solution plus générale, mais vous payez pour la généralité avec des frais supplémentaires. – tvanfosson

+0

@tvanfosson bien sûr, je suis totalement d'accord. –

1

LINQ:

Dim myhashtable As New Hashtable 
    myhashtable.Add("Teststring", "Hello") 
    myhashtable.Add("1TestString1", "World") 
    myhashtable.Add("2TestString2", "Test") 

For Each i As String In From Element In myhashtable.Cast(Of DictionaryEntry)() Let k = DirectCast(Element.Value, String) Where k.StartsWith("W") Select DirectCast(Element.Key, String) 
     MsgBox("This key has a matching value:" & i) 
    Next 

Mais mieux d'utiliser le dictionnaire si vous utilisez LINQ:

Dim d = New Dictionary(Of String, String)() 
    d.Add("Teststring", "Hello") 
    d.Add("1TestString1", "World") 
    d.Add("2TestString2", "Test") 

    For Each i As String In From element In d Where element.Value.StartsWith("W") Select element.Key 
     MsgBox("This key has a matching value:" & i) 
    Next 

Et au lieu de .StartsWith ("W"), vous pouvez bien sûr faire tout autre filtrage que vous voulez.

+0

Je ne sais pas si faire une requête LINQ dans le foreach est une bonne idée, parce que je suis sûr qu'il sera exécuté à chaque itération. Pas bon pour la performance. –

+0

plus c'est une chienne absolue à lire. –

+0

Ce serait un peu dommage, je l'ai fait comme ça partout dans un projet récent. Pouvez-vous confirmer cela à coup sûr? – Stefan

Questions connexes