簡體   English   中英

如何根據條件將C# LINQ代碼寫入select

[英]How to write C# LINQ code to select based on condition

我希望通過轉換方法將一種類型的列表轉換為另一種類型,但只是有選擇地(如果轉換結果為 null 或不是)。 它顯示在下面的代碼中。

private List<B> GetBList(List<A> aList)
{
    List<B> bList = new List<B>();
    foreach (A a in aList)
    {
        B b = GetB(a);
        if (b != null)
        {
            bList.Add(b);
        }
    }
    return bList;
}

private B GetB(A a)
{
    if (a != null)
    {
        return new B();
    }
    return null;
}

有沒有辦法使用 LINQ 編寫它,如下所示。 下面 function 的問題在於,即使轉換結果是 null,它也會始終移動數據。結果必須是數組(B 的數組),輸入必須是列表(A 的列表)。

private B[] GetBList(List<A> aList)
{
    return aList.Select(GetB)?.ToArray() ?? Array.Empty<A>();
}

請建議。 提前致謝!

您可以使用Select(x => GetB(x)) select 將返回轉換后的 object。 然后你應該用Where(x => x != null)過濾它。 然后將其轉換為array

注意我用過? aList as aList?.Select之后,它將處理aList object 為null的情況。

private B[] GetBList(List<A> aList)
{
    return aList?.Select(x => GetB(x)).Where(x => x != null).ToArray() ?? Array.Empty<B>();
}

編輯如果Select(x => GetB(x))也可以使用Select(GetB)代替。

private B[] GetBList(List<A> aList)
{
    return aList?.Select(GetB).Where(x => x != null).ToArray() ?? Array.Empty<B>();
}

我遇到過很多需要 function 的情況,因此我編寫了自己的擴展方法。 與此同時,我認為這樣做並沒有贏得任何東西,而你對Karan 的回答做得很好。 一方面,您不會在性能上獲得任何好處,另一方面,它只會增加代碼的復雜性和可讀性。

但是,它對我深入了解 LINQ 表達式、理解背后發生的事情以及理解 IEnumerable、ICollection 等的差異有很大幫助。

為了完整性和潛在的靈感,我還是分享了我的代碼:

public static IEnumerable<TResult> SelectByCondition<TInput, TResult>(this IEnumerable<TInput> input, Func<TInput, TResult> selector, Func<TResult, bool> checker) {
    using var enumerator = input.GetEnumerator();
    while (enumerator.MoveNext()) {
        var selection = selector(enumerator.Current);
        if (checker(selection)) {
            yield return selection;
        }
    }
}

在您的情況下,您可以這樣使用它:

aList?.SelectByCondition(GetB, x => x != null).ToArray() ?? Array.Empty<B>();

如果您碰巧多次遇到 null 檢查的場景,以下簡化可能仍然有用:

public static IEnumerable<TResult> SelectIfNotNull<TInput, TResult>(this IEnumerable<TInput> input, Func<TInput, TResult> selector) {
    using var enumerator = input.GetEnumerator();
    while (enumerator.MoveNext()) {
        var selection = selector(enumerator.Current);
        if (selection != null) {
            yield return selection;
        }
    }
}

然后可以簡化實際調用:

aList?.SelectIfNotNull(GetB).ToArray() ?? Array.Empty<B>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM