LINQ中的第二个“from”语句

时间:2009-05-22 17:09:13

标签: c# linq

我是LINQ的新手,我对该图书馆的了解来自Jon Skeet的书“C#In Depth 1”

我在过去几天阅读了很多关于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”,因为我不能找到一个普通代码的剪切器 - &gt; LINQ。

代码中的问题在哪里?

4 个答案:

答案 0 :(得分:3)

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

您可以调整包含吗?绕过1没有项目的分裂。

这是你想要做的吗?我认为第二个就像一个交叉连接,因为我理解你的问题所以没有必要。

答案 1 :(得分: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,并且找不到匹配项。

答案 2 :(得分: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;

答案 3 :(得分:0)

您需要执行连接,就像您要加入两个表一样。从SQL查询的角度思考这个过程......你有两个表... Ids和Lines。 Lines有两个字段,Id和Line,需要内部连接到Ids表。您可以使用以下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;