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

问题描述 投票:0回答:2

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

(cardPool是类型为'cardStats'的字典)我想做的事的伪装:

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

此代码显然无法正常工作,但仅是我正在寻找的功能的粗略示例。对于列表,我没有任何问题,但是对于字典,它确实让我感到困惑。

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

编辑:抱歉,我应该提到更多:Cardstats是值,键是int类型。我想筛选值(cardStats)并测试其属性,例如ID(int)或name(string)。

c# dictionary lambda where anonymous
2个回答
2
投票

[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();
}

0
投票

我将使用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;
}
© www.soinside.com 2019 - 2024. All rights reserved.