私は_System.Collections.Generic.Dictionary<A, B> dict
_を持っています。AとBはクラスで、インスタンス_A a
_(dict.ContainsKey(a)
はtrue)があります。
辞書から直接a
を含むKeyValuePairを取得することは可能ですか?
または、新しいKeyValuePairを作成する必要がありますか:new KeyValuePair<A, B>(a, dict[a])
?
新しいKeyValuePair
を作成する必要があります1 -ただし、KVPはいずれにしても値型(構造体)であることを忘れないでください。そのため、これを実行することで新しい非効率性を導入しているわけではありません。いずれにしても、KVPを返すメソッドはコピーを作成します。インスタンスを直接作成するだけです。
必要に応じて、拡張メソッドをIDictionary<TKey, TValue>
にいつでも追加できます。
public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key)
{
return new KeyValuePair<TKey, TValue>(key, dictionary[key]);
}
コメントに記載されているように、ディクショナリに格納されているキーがsameでなく、意味的に等しいだけである可能性があります-IEqualityComparer
(大文字と小文字を区別しないディクショナリなど)。その場合、上記のコードはディクショナリの実際のエントリではなく、検索のために指定したキーを持つエントリを返します。残念ながら、元のキーを見つける効率的な方法はありません-辞書を反復処理する必要があります:(
1 辞書エントリを反復処理して適切なエントリをその方法で見つけることができることは知っていましたが、O(1).
なので Dictionary<TKey, TValue>
実装IEnumerable<KeyValuePair<TKey, TValue>>
、linqを使用できます:
var pair = _dictionary.SingleOrDefault(p => p.Key == myKey);
この方法では"IPHone"
にアクセスできません:
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "IPHone", "TCP/IP honing tools" }
};
Console.WriteLine(dict["iPhone"]); // "TCP/IP honing tools"
Console.WriteLine( ??? ); // "IPHone"
現在のAPIではO(1)ソリューションはないようですが、すべてのエントリをループすることで機能します。
var keyValue = dict.First(p => dict.Comparer.Equals(p.Key, "iPhone"));
Console.WriteLine(keyValue.Key); // "IPHone"
Console.WriteLine(keyValue.Value); // "TCP/IP honing tools"
またはレイジーの拡張として:
[Pure]
public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
var comparer = dictionary.Comparer;
return dictionary.FirstOrDefault(p => comparer.Equals(p.Key, key));
}
私のために myDict.AsEnumerable
します...