簡體   English   中英

LINQ 惰性內連接

[英]LINQ Lazy Inner Join

有沒有辦法以懶惰的方式利用 LINQ API (內部)加入 collections ? 我面臨一種情況,我需要將多個 CSV 級聯關聯起來,如果“上游”CSV 為空,我希望避免不必要的解析操作:

ReadCsvRows(fileA).Join(
    ReadCsvRows(fileB), // why to parse B if A is empty?!
    ...
).Join(
    ReadCsvRows(fileC),
    ...
).Join(...)

請注意, ReadCsvRows方法位於接口后面,唯一的要求是該方法必須返回IEnumerable (如此處所示)。 為了保持“流暢”,我可以通過引入自定義擴展方法來解決這個問題

public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer, 
    Func<IEnumerable<TInner>> innerFunc, 
    Func<TOuter, TKey> outerKeySelector, 
    Func<TInner, TKey> innerKeySelector, 
    Func<TOuter, TInner, TResult> resultSelector) =>
        !outer.Any() ?
        Array.Empty<TResult>() :
        outer.Join(
            innerFunc(),
            outerKeySelector,
            innerKeySelector,
            resultSelector
        );

但想知道我對香草 LINQ API 有什么選擇。

如果我是你,我會將 ReadCsvRows(fileB) 和 ReadCsvRows(fileC) 拆分為兩個單獨的變量。 並添加一個“If”條件來確定是否應該執行“ReadCSVRows(fileB)”。

像這樣的東西:

List<FileATypeA> fileAData = ReadCsvRows(fileA);
List<FileATypeB> fileBData = new List<FileATypeB>();
List<FileATypeC> fileCData =  new List<FileTypeC>();

if(fileAData.Count() > 0)
    fileBData = ReadCsvRows(fileB);
if(fileBData.Count() > 0)
    fileCData = ReadCsvRows(fileC);

List<FinalType> final = from a in fileAData
                        join b in fileBData
                             on a.Key = b.Key
                        join c in fileCData
                             on b.Key = c.Key

看看這是否有幫助

您不需要自己的Join實現。 如果outer沒有記錄,標准System.Linq實現不枚舉inner序列。

因此,請檢查您的ReadCsvRows實現。 如果您在其正文中使用yield ,則不會出現不需要的讀取。

示意圖:

public static IEnumerable<Row> ReadCsvRows(string fileName)
{
   using var reader = new CsvReader(fileName);
   while (reader.ReadNext())
   {
      yield return reader.CurrentRow;
   }
}

在這種情況下,如果第一個序列沒有行,則不會調用new CsvReader(fileName)

暫無
暫無

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

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