我正在尝试创建一个函数,我可以传入一个函子/谓词,可以插入字典的'Where'方法。
(cardPool是'cardStats'类型的字典) 假想我想做什么:
void CardStats findCard(Predicate<CardStats> pred)
{
return cardPool.Where(pred);
}
这段代码显然不会工作,但只是我正在寻找的功能的一个粗略的例子。 我为列表设置这个没有任何问题,但对于一个词典,它确实让我感到难过。
任何帮助都会很棒,谢谢!
编辑: 对不起我应该提到更多:Cardstats是值,键是int类型。我想筛选值(cardStats)并测试它们的属性,如ID(int)或name(string)。
答案 0 :(得分:1)
Dictionary<TKey, TValue>
实现IEnumerable<KeyValuePair<TKey, TValue>>
,因此其Where
扩展方法采用Func<KeyValuePair<TKey, TValue>, bool>
类型的谓词。
你可以像这样实现你的方法:
void CardStats findCard(Func<int, CardStats, bool> pred)
{
return cardPool.Where(kv => pred(kv.Key, kv.Value))
.Select(kv => kv.Value)
.FirstOrDefault();
}
并像这样使用它:
CardStats stats = myCards.findCard((id, stats) => id == 7);
或
CardStats stats = myCards.findCard((id, stats) => stats.Name == "Ace of Clubs");
请注意,在字典上使用Where
不会利用字典的快速查找功能,并且基本上将其视为键值对的线性集合。
<小时/> 还有一条评论:我建议提供一种方法,如果有几张卡,则返回
IEnumerable
找到的卡片。或者你可以提供一个这样做,并且只返回第一个匹配:
void IEnumerable<CardStats> findCards(Func<int, CardStats, bool> pred)
{
return cardPool.Where(kv => pred(kv.Key, kv.Value))
.Select(kv => kv.Value);
}
void CardStats findCard(Func<int, CardStats, bool> pred)
{
return findCards(pred).FirstOrDefault();
}
答案 1 :(得分:1)
我将使用FirstOrDefault作为第一条语句,因为它将在找到匹配的元素后立即停止。另一件事是,我将考虑使用除字典以外的其他内容-因为如果将其用于索引目的,则以这种方式使用时会被滥用。
无论如何,这是我将使用的代码:
public CardStats Find(Func<CardStats, bool> predicate)
{
KeyValuePair<int, Roster> kvCard = cardPool.FirstOrDefault(kvp => predicate(kvp.Value));
if (kvCard.Equals(default(KeyValuePair<int, Roster>)))
return null;
return kvCard.Value;
}