2009-06-26 15 views

Antwort

8

Ich bin nicht sicher, ob Sie den Wert in der neuen KeyValuePair wollen eine zählbare dieser Art oder ein einzelnes Element zu sein. Ist hier beide Versionen

IEnumerable Version

var toReturn = source.Select(x => new KeyValuePair<SomeType,IEnumerable<SomeOtherType>>(x.Key, x.Value.Take(1)); 

Nicht Enumerable Version

var toReturn = source.Select(x => new KeyValuePair<SomeType,SomeOtherType>(x.Key,x.Value.First()); 
+1

Dank Haufen, brauchte ich erste Version. Ich habe das tatsächlich ausprobiert, aber vergessen, die Typen in KeyValuePair anzugeben und bekam einen Fehler. – epitka

6

Alles, was Sie fehlt, ist die Art von KeyValuePair zu verwenden. Sie könnten Jareds Lambda-Ausdruck-Version verwenden, oder wenn Sie die Abfrage Ausdruck Syntax mag:

var toReturn = from kv in source 
       select new KeyValuePair<MyType, OtherType>(kv.Key, 
                  kv.Value.First()); 

Wenn Sie nicht wollen, explizit die Typargumente angeben, können Sie Ihre eigene Helfer Klasse und Verwendung Typinferenz schaffen könnte:

// Non-generic helper class. 
public static class KeyValuePair 
{ 
    public static KeyValuePair<TKey, TValue> Of(TKey key, TValue value) 
    { 
     return new KeyValuePair<TKey, TValue>(key, value); 
    } 
} 

, bei der Abfrage zeigen wird:

var toReturn = from kv in source 
       select KeyValuePair.Of(kv.Key, kv.Value.First()); 

oder

var toReturn = source.Select(kv => KeyValuePair.Of(kv.Key, kv.Value.First()); 

EDIT: Ups - ich denke, ich würde Ihre Frage auch falsch lesen. Wenn Sie es möchten, von der exakt gleichen Art sein, dh mit dem Wert zu enumerable sein, verwenden Sie einfach Take(1) statt First():

var toReturn = source.Select(kv => KeyValuePair.Of(kv.Key, kv.Value.Take(1)); 

(Ist geben nicht schön Inferenz :)

+0

Ich rief stattdessen meine "Of" -Methode "Create", aber ich liebe diesen Ansatz wirklich, wenn ich KeyValuePairs manuell erstellen muss ... –

0

Warum? Sie möchten eine Sammlung des gleichen Typs erhalten? Wenn Sie nur das erste Element haben, benötigen Sie keine Sammlung (IEnumerable<OtherType>), sondern einen einzelnen Wert (OtherType).

Diese (wie diejenige, die Sie geschrieben) korrekt sein sollte (Sie werden allgemeine Parameter nur für die KeyValuePair hinzufügen müssen)

var toReturn = from kv in source select new KeyValuePair<SomeType, OtherType>(kv.Key, kv.Value.First()); 

Wenn Sie wirklich eine Sammlung von der gleichen Art erhalten möchten, schreiben

Hinweis: Sie müssen dem KeyValuePair keine expliziten Typargumente geben, wenn Sie dies in eine generische Funktion einschließen.

KeyValuePair<TKey, TValue> Pair<TKey, TValue>(TKey key, TValue value) { 
    return new KeyValuePair<TKey, TValue>(key, value); 
} 
// 
var foo = Pair(1, "Hello"); 
+0

Ich brauchte in einem gleichen Typ, um es an die gleiche Methode zu übergeben, die die andere behandelt ein. Dies ist nach Datumserstellung desc angeordnet, und ich muss alle oder nur die neuesten zeigen. – epitka

1
var toReturn = source 
.ToDictionary(
    kvp => kvp.Key, 
    kvp => kvp.Value.Take(1) 
); 
Verwandte Themen