Check if KeyValuePair exists with LINQ's FirstOrDefault
I have a dictionary of type
Dictionary<Guid,int>
I want to return the first instance where a condition is met using
var available = m_AvailableDict.FirstOrDefault(p => p.Value == 0)
However, how do I check if I'm actually getting back a KeyValuePair? I can't seem to use != or == to check against default(KeyValuePair) without a compiler error. There is a similar thread here that doesn't quite seem to have a solution. I'm actually able to solve my particular problem by getting the key and checking the default of Guid, but I'm curious if there's a good way of doing this with the keyvaluepair. Thanks
如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

评论(6)


What you want is an Any
method that gives you the matching element as well. You can easily write this method yourself.
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;
}
}


I suggest you change it in this way:
var query = m_AvailableDict.Where(p => p.Value == 0).Take(1).ToList();
You can then see whether the list is empty or not, and take the first value if it's not, e.g.
if (query.Count == 0)
{
// Take action accordingly
}
else
{
Guid key = query[0].Key;
// Use the key
}
Note that there's no real concept of a "first" entry in a dictionary - the order in which it's iterated is not well-defined. If you want to get the key/value pair which was first entered with that value, you'll need an order-preserving dictionary of some kind.
(This is assuming you actually want to know the key - if you're just after an existence check, Marc's solution is the most appropriate.)

If you just care about existence, you could use ContainsValue(0)
or Any(p => p.Value == 0)
instead? Searching by value is unusual for a Dictionary<,>
; if you were searching by key, you could use TryGetValue
.
One other approach:
var record = data.Where(p => p.Value == 1)
.Select(p => new { Key = p.Key, Value = p.Value })
.FirstOrDefault();
This returns a class - so will be null
if not found.
发布评论
需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。