2016-03-29 11 views
1

C# -Code wie folgt:C# Namevaluecollection verschiedene Werte

NameValueCollection nvc = new NameValueCollection(); 
nvc.Add("color", "red"); 
nvc.Add("size", "s"); 
nvc.Add("color", "red"); 
nvc.Add("size", "m"); 
nvc.Add("color", "red"); 
nvc.Add("size", "l"); 

//blue 
nvc.Add("color", "blue"); 
nvc.Add("size", "m"); 
nvc.Add("color", "blue"); 
nvc.Add("size", "l"); 
//green 
nvc.Add("color", "green"); 
nvc.Add("size", "s"); 
nvc.Add("color", "green"); 
nvc.Add("size", "m"); 
nvc.Add("color", "green"); 
nvc.Add("size", "l"); 

tatsächliche Ergebnis:

color:red,red,red,blue,blue,green,green,green 
size:s,m,l,m,l,s,m,l 

Hoffnung Ergebnis:

color:red,blue,green  
size:s,m,l 
+1

Sie müssen Sie zeigen, haben auf diese ein zu gehen hatte. Hast du irgendeinen Code geschrieben? Wenn ja, poste es. –

Antwort

0

Ich bin mir nicht sicher in Ihrem Anwendungsfall, NameValueCollection ermöglicht Duplikate besser zu verwenden Dictionary für solche Fälle.

Noch können Sie etwas unter NameValueCollection tun, um die gewünschten Ergebnisse zu erhalten.

var results = nvc.AllKeys 
    .GroupBy(g=>g) 
    .Select(s=> 
      new 
      { 
       key = s.Key, 
       values = nvc.GetValues(s.Key).Distinct() 
      }); 


foreach(var result in results) 
{ 
    Console.WriteLine("{0}- {1}", result.key, string.Join(",", result.values) ; 
} 

Arbeiten Example

+0

Warum würden Sie eine Datenstruktur verwenden, die mit wer weiß wie viele Duplikate aufgebläht werden könnte und dann die Duplikate später entfernen? Lieber die Datenstruktur mit Duplikaten umgehen lassen! – ErikE

+0

Das stimmt, das ist mein erster Punkt. –

2

Einige Gedanken für Sie:

  1. NameValueCollection ermöglicht doppelte Werte. Verwenden Sie eine Dictionary<string, string>.
  2. NameValueCollection ist ein älteres Objekt, das nur stark auf string, string typisiert ist. Dictionary ist flexibler, weil Sie die Typparameter angeben können.
  3. Wenn Sie Dictionary verwenden, beachten Sie, dass Sie Fehler erhalten, wenn Sie versuchen, denselben Schlüssel zweimal hinzuzufügen. Dies kann durch geringfügige Änderung der Syntax behoben werden. Statt Add(), benutzen Sie einfach den Indexer:

    var myDict = new Dictionary<string, string>(); 
    myDict["color"] = "blue"; 
    myDict["color"] = "blue"; // no harm doing this twice 
    

Nach meiner Erfahrung Saiten ganz über dem Platz ist ein Weg, Wanzen, einschleichen zu lassen und macht es einfach, Fehler zu machen (hmmm, fragen sich, wie Ich weiß das?). Es ist zu einfach, etwas falsch zu schreiben oder einer Farbe eine Größe zuzuordnen oder umgekehrt.

Gibt es einen Grund, warum Sie die Konzepte in Ihrem Code nicht stark eingeben können?

public abstract class ProductAttribute { } 

public sealed class Color : ProductAttribute { 
    private Color(string value) { Value = value; } 
    public Value { get; } 

    public static readonly Blue = new Color("blue"); 
    public static readonly Green = new Color("green"); 

    private static readonly IReadOnlyDictionary<string, Color> _colorDict = 
     new ReadOnlyDictionary<string, Color>(
      new List<Color> { 
      Blue, Green 
      }.ToDictionary(color => color.Value, color => color) 
     ); 

    public static Color GetColor(string value) { 
     Color color; 
     _colorDict.TryGetValue(value, out color); 
     return color; 
    } 
} 

Dann tun Sie etwas ähnliches für die Größen. Dies ist nur eine Idee, vielleicht nicht sehr flexibel (Sie müssen den Code ändern, um neue Werte hinzuzufügen), aber es sollte Ihnen zeigen, was möglich ist.

Aber schauen Sie, was Sie jetzt tun können:

var attrs = new HashSet<ProductAttribute>; 
attrs.Add(Color.Blue); 
attrs.Add(Color.Green); 
attrs.Add(Color.Blue); // no problem 
attrs.Add(Color.GetColor("blue")); // no problem 
attrs.Add(Size.Small); 
attrs.Add(Size.Medium); 
attrs.Add(Size.Medium); // no problem 

Eine Möglichkeit, mit den ProductAttribute Klassen zu arbeiten, ist wie so:

foreach (ProductAttribute attr in attrs) { 
    Color color = attr as Color; 
    if (color != null) { 
     // work with color 
    } 
} 

Alternativ können Sie auch eine ProductAttributeType Enum erstellen, fügen Sie es als ein Parameter in dem ProductAttribute-Konstruktor und es in einer schreibgeschützten abstrakten Eigenschaft in der Klasse ProductAttribute verfügbar machen. Dann übergeben alle Ihre Unterklassen in welcher Art sie sind, und Sie können leicht den Typ von etwas gerade attr.ProductAttributeType == ProductAttributeType.Color zum Beispiel zu tun bekommen.

+0

Zusätzlich zu 'Dictionary ' Beachten Sie, dass die 'Add'-Methode beim Hinzufügen eines Duplikats eine Ausnahme auslöst, während dieser Index-Accessor nur den vorhandenen Wert überschreibt. Wählen Sie, wie Sie möchten. – ZoolWay

+0

@ZoolWay Ich wollte das erwähnen aber vergessen. Danke für die Erinnerung. – ErikE