Frage

Als Ergebnis einer anderen Frage, die ich hier fragte ich einen HashSet für meine Objekte verwenden möchten

Ich werde Objekte erstellen einen String und einen Verweis auf seinen Besitzer enthalten.

public class Synonym
{
   private string name;
   private Stock owner;
   public Stock(string NameSynonym, Stock stock)
   {
       name=NameSynonym;
       owner=stock
   }
   // [+ 'get' for 'name' and 'owner']
}

Ich verstehe, ich brauche einen Vergleich, aber es nie benutzt. Soll ich eine eigene Klasse erstellen? wie:

public class SynonymComparer : IComparer<Synonym>
{
   public int Compare(Synonym One, Synonym Two)
   { // Should I test if 'One == null'  or  'Two == null'  ???? 
       return String.Compare(One.Name, Two.Name, true); // Caseinsesitive
   }

}

Ich ziehe eine Funktion (oder verschachtelte Klasse [vielleicht ein Singleton?] Falls erforderlich) haben TEIL der Klasse Synonym zu sein, statt eines anderen (unabhängig) Klasse. Ist das möglich?

Über Nutzung: Da ich nie diese Art der Sache benutzt, bevor ich glaube, ich muss eine Suche (string NameSynonym) Funktion innerhalb der Klasse Synonym schreiben, aber wie soll ich das tun?

public class SynonymManager
{ 
    private HashSet<SynonymComparer<Synonym>> ListOfSynonyms;

    public SynonymManager()
    {
        ListOfSymnonyms = new HashSet<SynonymComparer<Synonym>>();
    }

    public void SomeFunction()
    { // Just a function to add 2 sysnonyms to 1 stock
        Stock stock = GetStock("General Motors");
        Synonym otherName = new Synonym("GM", stock);
        ListOfSynonyms.Add(otherName);
        Synonym otherName = new Synonym("Gen. Motors", stock);
        ListOfSynonyms.Add(otherName);
    }

    public Synonym Find(string NameSynomym)
    {
       return ListOfSynonyms.??????(NameSynonym);
    }
 }

In dem obigen Code Ich weiß nicht, wie die ‚Suchen‘ Methode zu implementieren. Wie soll ich das tun?

Jede Hilfe wird geschätzt (PS Wenn meine Vorstellungen darüber, wie sollte es völlig falsch umgesetzt werden sollen, lassen Sie mich es mich wissen und sagen, wie zu implementieren)

War es hilfreich?

Lösung

Ein HashSet braucht keine IComparer<T> - es eine IEqualityComparer<T>, wie

braucht
public class SynonymComparer : IEqualityComparer<Synonym>      
{
   public bool Equals(Synonym one, Synonym two)
   {
        // Adjust according to requirements.
        return StringComparer.InvariantCultureIgnoreCase
                             .Equals(one.Name, two.Name);

   }

   public int GetHashCode(Synonym item)
   {
        return StringComparer.InvariantCultureIgnoreCase
                             .GetHashCode(item.Name);

   }
}

Allerdings Ihr aktueller Code kompiliert nur weil Sie eine Reihe von sind die Schaffung comparers , anstatt eine Reihe von Synonyme .

Außerdem, ich glaube nicht, dass Sie wirklich einen Satz überhaupt wollen. Es scheint mir, dass Sie ein Wörterbuch oder eine Lookup wollen, so dass Sie die Synonyme für einen bestimmten Namen finden:

public class SynonymManager
{ 
    private readonly IDictionary<string, Synonym> synonyms = new
        Dictionary<string, Synonym>();

    private void Add(Synonym synonym)
    {
        // This will overwrite any existing synonym with the same name.
        synonyms[synonym.Name] = synonym;
    }

    public void SomeFunction()
    { 
        // Just a function to add 2 synonyms to 1 stock.
        Stock stock = GetStock("General Motors");
        Synonym otherName = new Synonym("GM", stock);
        Add(otherName);
        ListOfSynonyms.Add(otherName);
        otherName = new Synonym("Gen. Motors", stock);
        Add(otherName);
    }

    public Synonym Find(string nameSynonym)
    {
       // This will throw an exception if you don't have
       // a synonym of the right name.  Do you want that?
       return synonyms[nameSynonym];
    }
}

Beachten Sie, dass es einige Fragen oben im Code, wie Sie wollen, dass es in verschiedenen Fällen verhalten. Sie müssen heraus genau , was Sie wollen, es zu tun.

EDIT: Wenn Sie mehrere Bestände für ein einzelnes Synonym speichern zu können, Sie effektiv ein Lookup<string, Stock> wollen - aber das ist unveränderlich. Sie sind wahrscheinlich am besten Speichern eines Dictionary<string, List<Stock>>; eine Liste der Aktien für jede Saite.

In Bezug auf einen Fehler nicht aus Find werfen, Sie bei Dictionary.TryGetValue aussehen sollten, die keine Ausnahme auslösen, wenn der Schlüssel nicht gefunden wird (und auch zurück, ob die Taste beträgt gefunden ); der abgebildete Wert "zurückgegeben" in einem Out-Parameter ist.

Andere Tipps

Wäre es nicht sinnvoll sein, die Synonym Klasse ganz verschrotten und hat Liste von Synonymen ein Dictonary zu sein (oder, wenn es so etwas gibt, HashDictionary) von Strings?

(Ich bin nicht sehr vertraut mit C # -Typen, aber ich hoffe, dass diese allgemeine Idee vermittelt)

Die Antwort, die ich empfehlen (herausgegeben, jetzt respektiert den Fall):

    IDictionary<string, Stock>>  ListOfSynonyms = new Dictionary<string,Stock>>(); 
    IDictionary<string, string>> ListOfSynForms = new Dictionary<string,string>>(); 
    class Stock 
    {   
        ...
        Stock addSynonym(String syn) 
        {
            ListOfSynForms[syn.ToUpper()] = syn;
            return ListOfSynonyms[syn.ToUpper()] = this;
        }
        Array findSynonyms()
        {
            return ListOfSynonyms.findKeysFromValue(this).map(x => ListOfSynForms[x]);
        }
    }

    ...
    GetStock("General Motors").addSynonym('GM').addSynonym('Gen. Motors');
    ...
    try  
    {
        ... ListOfSynonyms[synonym].name ...
    }  
    catch (OutOfBounds e) 
    {
        ...
    } 
    ...
    // output everything that is synonymous to GM. This is mix of C# and Python
    ... GetStock('General Motors').findSynonyms()
    // test if there is a synonym
    if (input in ListOfSynonyms) 
    {
        ...
    }

Sie können immer LINQ verwenden, um die Lookup zu tun:

public Synonym Find(string NameSynomym)
{
   return ListOfSynonyms.SingleOrDefault(x => x.Name == NameSynomym);
}

Aber haben Sie darüber nachgedacht, anstatt ein Wörterbuch verwenden, ich glaube, es ist besser für das Extrahieren einzelner Mitglieder geeignet ist, und Sie können garantieren, noch, dass es keine Duplikate sind basierend auf dem Schlüssel, den Sie wählen.

Ich bin nicht sicher, dass Lookup-Zeit von SingleOrDefault ist, aber ich bin mir ziemlich sicher, dass es linear (O (n)), so dass, wenn Lookup-Zeit für Sie wichtig ist, ein Wörterbuch Sie mit O zur Verfügung stellt (1) Lookup Zeit .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top