LINQ 查询 - 根据具有与字符串匹配的属性的值来选择键?

发布于 2024-11-16 03:54:49 字数 714 浏览 2 评论 0原文

我有一个 IDictionary

,我需要选择 Bar.Prop1 与字符串值匹配的第一个 Foo。

public class Foo { }

public class Bar
{
    public String Prop1 { get; set; }
}

现在我已经这样了...

foreach (var kvp in MyDictionary)
{
    if (kvp.Value.Prop1 == theString)
    {
        var key = kvp.Key;
        //Do something with it
        break;
    }
}

但这看起来不像 LINQ 查询那么干净。 ReSharper 将其变成:

foreach (var kvp in MyDictionary.Where(kvp => kvp.Value.Prop1 == theString))
{
    var key = kvp.Key;
    //Do something with it
    //break; is unnecessary because I only get one kvp back anyways.
}

我只想要第一个匹配的项目,因为我不希望返回多个 KVP。这违背了业务逻辑,因此单元测试会解决这个问题。

I have an IDictionary

I need to select the first Foo where the Bar.Prop1 matches a string value.

public class Foo { }

public class Bar
{
    public String Prop1 { get; set; }
}

right now I have it like so...

foreach (var kvp in MyDictionary)
{
    if (kvp.Value.Prop1 == theString)
    {
        var key = kvp.Key;
        //Do something with it
        break;
    }
}

But that just doesn't seem as clean as a LINQ Query is. ReSharper turned it into:

foreach (var kvp in MyDictionary.Where(kvp => kvp.Value.Prop1 == theString))
{
    var key = kvp.Key;
    //Do something with it
    //break; is unnecessary because I only get one kvp back anyways.
}

I only want the very first item that matches, because I don't ever expect to get back more than one KVP. That goes against the business logic, so Unit Testing takes care of that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疑心病 2024-11-23 03:54:49

我只想要第一个项目
匹配,因为我从来没想过
拿回超过 1 个 KVP。那
违背业务逻辑,所以
单元测试负责解决这个问题。

如果是这种情况,我认为您需要使用更强有力的代码保证您的意图,这就是 Single (或 SingleOrDefault)方法。 First 将返回与给定谓词匹配的任意多个对象中的第一个对象。如果很多违背了您的期望和业务规则,这似乎是一个错误。就这样对待它。

var key = MyDictionary.Single(pair => pair.Value.Prop1 == someValue).Key;

使用 Single 时,如果序列中存在多个匹配项,则会导致异常。

SingleOrDefault 允许 0 或 1,但不能更多。如果使用这种方法,您需要捕获结果并在执行其他操作(触发方法、访问属性等)之前与 null 进行比较。

I only want the very first item that
matches, because I don't ever expect
to get back more than one KVP. That
goes against the business logic, so
Unit Testing takes care of that.

If this is the case, I would argue you need to use a stronger code guarantee of your intention, and that would be the Single (or SingleOrDefault) method. First is going to return the first object of arbitrarily many that match a given predicate. If many goes against your expectations and business rules, this seems to be an error. Treat it as such.

var key = MyDictionary.Single(pair => pair.Value.Prop1 == someValue).Key;

With Single, if there is more than one matching item in a sequence, it will result in an exception.

SingleOrDefault allows for 0 or 1, but never more. If using this approach, you'd want to capture the result and compare to null before performing additional operations with it (firing methods, accessing properties, etc.).

不爱素颜 2024-11-23 03:54:49
var key = MyDictionary.First(kvp => kvp.Value.Prop1 == theString).Key;
var key = MyDictionary.First(kvp => kvp.Value.Prop1 == theString).Key;
停滞 2024-11-23 03:54:49

@Bala R 的答案是正确的,但 Anthony Pegram 在他对 OP 的评论中提出了非常好的观点。如果您使用不同的键多次执行此操作,那么您应该做的是反转字典,这样您就不必每次需要一个值时都遍历整个集合。

// Do this just once: it's expensive
var reverseDict = MyDictionary.ToDictionary(kvp => kvp.Value.Prop1, kvp => kvp.Key);

...
// Do this as many times as you need: it's cheap
var key = reverseDict[someValue];

@Bala R's answer is correct, but Anthony Pegram makes a very good point in his comment on the OP. If you're doing this more than a few times with different keys, what you should do instead is reverse the dictionary, so you don't have to traverse the entire collection every time you want a value.

// Do this just once: it's expensive
var reverseDict = MyDictionary.ToDictionary(kvp => kvp.Value.Prop1, kvp => kvp.Key);

...
// Do this as many times as you need: it's cheap
var key = reverseDict[someValue];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文