C#Dictionary搜索谓词作为方法参数

时间:2014-12-23 21:12:52

标签: c# dictionary lambda where anonymous

我正在尝试创建一个函数,我可以传入一个函子/谓词,可以插入字典的'Where'方法。

(cardPool是'cardStats'类型的字典) 假想我想做什么:

void CardStats findCard(Predicate<CardStats> pred)
{
    return cardPool.Where(pred);
}

这段代码显然不会工作,但只是我正在寻找的功能的一个粗略的例子。 我为列表设置这个没有任何问题,但对于一个词典,它确实让我感到难过。

任何帮助都会很棒,谢谢!

编辑: 对不起我应该提到更多:Cardstats是值,键是int类型。我想筛选值(cardStats)并测试它们的属性,如ID(int)或name(string)。

2 个答案:

答案 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;
}