web-dev-qa-db-ja.com

LINQのFirstOrDefaultでKeyValuePairが存在するかどうかを確認します

タイプの辞書があります

Dictionary<Guid,int>

を使用して条件が満たされた最初のインスタンスを返したい

var available = m_AvailableDict.FirstOrDefault(p => p.Value == 0)

ただし、実際にKeyValuePairを取得しているかどうかを確認するにはどうすればよいですか? !=または==を使用して、コンパイラエラーなしでdefault(KeyValuePair)をチェックすることはできません。同様のスレッドがあります here 解決策がないようです。私は実際にキーを取得し、Guidのデフォルトをチェックすることで特定の問題を解決できますが、keyvaluepairでこれを行う良い方法があるかどうか興味があります。ありがとう

71
Steve

存在だけを気にする場合は、代わりにContainsValue(0)またはAny(p => p.Value == 0)を使用できますか? valueによる検索は、Dictionary<,>;キーで検索する場合は、TryGetValueを使用できます。

もう1つのアプローチ:

var record = data.Where(p => p.Value == 1)
     .Select(p => new { Key = p.Key, Value = p.Value })
     .FirstOrDefault();

これはclassを返します-見つからない場合はnullになります。

103
Marc Gravell

この方法で変更することをお勧めします。

var query = m_AvailableDict.Where(p => p.Value == 0).Take(1).ToList();

次に、リストが空かどうかを確認し、空でない場合は最初の値を取得します。

if (query.Count == 0)
{
    // Take action accordingly
}
else
{
    Guid key = query[0].Key;
    // Use the key
}

辞書には「最初の」エントリという実際の概念はないことに注意してください-繰り返される順序は明確に定義されていません。その値でfirstに入力されたキーと値のペアを取得する場合は、何らかの種類の順序保存辞書が必要になります。

(これは、実際にキーを知りたいと仮定している-存在チェックの直後なら、 Marcの解 が最も適切です。)

25
Jon Skeet

Default()キーワードを使用します。

bool exists = !available.Equals(default(KeyValuePair<Guid, int>));
13

必要なのは、一致する要素も提供するAnyメソッドです。このメソッドは自分で簡単に作成できます。

public static class IEnumerableExtensions
{
  public static bool TryGetFirst<TSource>(this IEnumerable<TSource> source,
                                          Func<TSource, bool> predicate,
                                          out TSource first)
  {
    foreach (TSource item in source)
    {
      if (predicate(item))
      {
        first = item;
        return true;
      }
    }

    first = default(TSource);
    return false;
  }
}
9
Samuel

あなたがチェックすることができます

available.Key==Guid.Empty
2
pomarc