这可以通过单个 LINQ 查询来实现吗?

发布于 2024-12-09 19:31:32 字数 472 浏览 2 评论 0原文

假设我有一个 IEnumerable 类型的给定对象,它是方法 SomeMethod() 的返回值,并且不包含重复元素。我希望能够在单个 LINQ 查询中“压缩”以下几行:

IEnumerable<string> someList = SomeMethod();

if (someList.Contains(givenString))
{
    return (someList.Where(givenString));
}
else
{
    return (someList);
}

编辑: 我错误地使用了 Single 而不是 First。现已更正。

我知道我可以使用三元运算符“压缩”它,但这不是重点。我只想列出能够用一行来实现这一点。这可能吗?

Suppose I have a given object of type IEnumerable<string> which is the return value of method SomeMethod(), and which contains no repeated elements. I would like to be able to "zip" the following lines in a single LINQ query:

IEnumerable<string> someList = SomeMethod();

if (someList.Contains(givenString))
{
    return (someList.Where(givenString));
}
else
{
    return (someList);
}

Edit: I mistakenly used Single instead of First. Corrected now.

I know I can "zip" this by using the ternary operator, but that's just not the point. I would just list to be able to achieve this with a single line. Is that possible?

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

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

发布评论

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

评论(4

饭团 2024-12-16 19:31:32

这将返回具有给定字符串的项目或所有项目(如果给定的字符串不存在于列表中):

someList.Where(i => i == givenString || !someList.Contains(givenString))

This will return items with given string or all items if given is not present in the list:

someList.Where(i => i == givenString || !someList.Contains(givenString))
小女人ら 2024-12-16 19:31:32

您所需输出的性质要求您要么像现在一样发出两个数据请求,要么缓冲不匹配项,以便在未找到匹配项时返回。后者在实际获取数据是一个相对昂贵的调用的情况下特别有用(例如:数据库查询或 WCF 服务)。缓冲方法如下所示:

static IEnumerable<T> AllIfNone<T>(this IEnumerable<T> source, 
                                   Func<T, bool> predicate)
{
    //argument checking ignored for sample purposes
    var buffer = new List<T>();
    bool foundFirst = false;
    foreach (var item in source)
    {
        if (predicate(item))
        {
            foundFirst = true;
            yield return item;
        }
        else if (!foundFirst)
        {
            buffer.Add(item);
        }
    }

    if (!foundFirst)
    {
        foreach (var item in buffer)
        {
            yield return item;
        }
    }
}

此方法的惰性是 WhereToList 的惰性,具体取决于集合是否包含匹配项。如果是这样,您应该获得类似于 Where 的执行。如果没有,您将大致了解调用 ToList 的执行情况(包含所有失败的过滤器检查的开销)并迭代结果。

The nature of your desired output requires that you either make two requests for the data, like you are now, or buffer the non-matches to return if no matches are found. The later would be especially useful in cases where actually getting the data is a relatively expensive call (eg: database query or WCF service). The buffering method would look like this:

static IEnumerable<T> AllIfNone<T>(this IEnumerable<T> source, 
                                   Func<T, bool> predicate)
{
    //argument checking ignored for sample purposes
    var buffer = new List<T>();
    bool foundFirst = false;
    foreach (var item in source)
    {
        if (predicate(item))
        {
            foundFirst = true;
            yield return item;
        }
        else if (!foundFirst)
        {
            buffer.Add(item);
        }
    }

    if (!foundFirst)
    {
        foreach (var item in buffer)
        {
            yield return item;
        }
    }
}

The laziness of this method is either that of Where or ToList depending on if the collection contains a match or not. If it does, you should get execution similar to Where. If not, you will get roughly the execution of calling ToList (with the overhead of all the failed filter checks) and iterating the result.

把昨日还给我 2024-12-16 19:31:32

三元运算符有什么问题?

someList.Any(s => s == givenString) ? someList.Where(s => s == givenString) : someList;

最好先执行“Where”,然后执行“Any”,但我不知道如何单行执行此操作。

var reducedEnumerable = someList.Where(s => s == givenString);

return reducedEnumerable.Any() ? reducedEnumerable : someList;

What is wrong with the ternary operator?

someList.Any(s => s == givenString) ? someList.Where(s => s == givenString) : someList;

It would be better to do the Where followed by the Any but I can't think of how to one-line that.

var reducedEnumerable = someList.Where(s => s == givenString);

return reducedEnumerable.Any() ? reducedEnumerable : someList;
各空 2024-12-16 19:31:32

无法更改方法的返回类型,这就是您所要求的。第一个条件返回字符串,第二个条件返回字符串集合。

只需返回 IEnumerable 集合,然后对返回值调用 Single 即可,如下所示:

string test = ReturnCollectionOfStrings().Single(x => x == "test");

It is not possible to change the return type on the method, which is what you're asking. The first condition returns a string and the second condition returns a collection of strings.

Just return the IEnumerable<string> collection, and call Single on the return value like this:

string test = ReturnCollectionOfStrings().Single(x => x == "test");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文