2009-05-22 95 views
2

我是新來的LINQ,我對圖書館的知識是從喬恩斯基特的書「C#在深度1」二「從」聲明LINQ

我在過去的日子裏看了很多關於LINQ教程包括Skeet的書,但我永遠無法找到顯示正常C#代碼的代碼片段,然後找到使用LINQ的代碼的較短版本,因此讀者可以瞭解到底是什麼。

我的問題: 下面的函數打開一個文本文件並搜索文本文件中特定位置的數字。數字(我在代碼中使用了ID)從1開始到25000,有幾個(例如沒有生命25,但24,23,26,27等)。 我希望代碼複製數組「Ids」中的行。它不是一個數組,我只是新的,我不知道LINQ的其他任何東西都會更方便。

public static IEnumerable<string> ReadLines(StreamReader reader) 
    { 
     while (!reader.EndOfStream) 
     { 
      yield return reader.ReadLine(); 
     } 
    } 

    static void Filter(string filename) 
    { 
     using(var writer = File.CreateText(Application.StartupPath + "\\temp\\test.txt")) 
     { 
      using (var reader = File.OpenText(filename)) 
      { 
       int[] Ids = { 14652, 14653, 14654, 14655, 14656, 14657, 14658, 14659, 14660 }; 
       var myId = from id in Ids 
          from line in ReadLines(reader) 
          let items = line.Split('\t') 
          where items.Length > 1 
          let ItemId = int.Parse(items[1]) 
          where ItemId == id 
          select line; 
       foreach (var id in myId) 
       { 
        writer.WriteLine(id); 
       } 

      } 
     } 
    } 

它寫道:它只寫一行數字,這是Ids []數組(14652)的第一個成員。

我不得不添加第二個'from',它放在代碼中的第一位,所以它會檢查它的數組中的每個成員。我將from語句看作「while」,因爲我無法'找到一個正常代碼 - > linq的snipper。

代碼中的問題在哪裏?

回答

2

它只寫入與頭號線,這是IDS []數組(14652)的第一個成員。 代碼中的問題在哪裏?

from id in Ids 
from line in ReadLines(reader) 

此代碼是概念上像(忽略延遲執行):

foreach(int id in Ids) 
{ 
    foreach(string line in ReadLines(reader) 
    { 
    ... 
    } 
} 

這將爲第一個ID工作的偉大,但隨後的讀者將在該文件的末尾第二個ID,沒有匹配將被發現。

3
from line in ReadLines(reader) 
where Ids.Contains(line.Split('\t')[1]) 
select line; 

您可以調整包含?以避開在1處沒有物品的拆分。

這是你想要做的嗎?我認爲第二個就像是一個交叉連接,因爲我理解你的問題並不是必需的。

+0

謝謝!長度= 15; – 2009-05-22 17:31:34

1

此代碼未經測試,但您是否在尋找類似的東西?

var lines = from line in ReadLines(reader) 
      let items = line.Split('\t') 
      where items.Length > 1 
      select new { Text = line, ItemId = int.Parse(items[1]) }; 

var myId = from id in Ids 
      join line in lines on id equals line.ItemId 
      select line.Text; 
0

您需要執行連接,就像連接兩個表一樣。從SQL查詢的角度思考過程...你有兩個表... Ids和Lines。行有兩個字段,即Id和Line,並且需要將內部聯接到Id表。您可以使用以下LINQ查詢完成此操作:

var lines = from id in Ids 
      join line in 
      (
       from l in ReadLines(reader) 
       let items = l.Split('\t') 
       where items.Length > 1 
       select new { Id = int.Parse(items[1]), Line = l } 
      ) on id equals line.Id 
      select line.Line;