简体   繁体   English

LINQ中的第二个“ from”语句

[英]Second “from” statement in LINQ

I'm new to LINQ,My knowledge on that library is from Jon Skeet's book "C# In Depth 1" 我是LINQ的新手,我对该图书馆的了解来自Jon Skeet的书“ C#In Depth 1”

I read a lot of tutorials about LINQ in the past days including Skeet's book,but I could never find out a code snippet showing a normal C# code and then the shorter version of that code with LINQ so the reader can understand what does what. 在过去的几天里,我读了很多有关LINQ的教程,包括Skeet的书,但是我永远找不到一个显示正常C#代码的代码片段,然后再用LINQ编写该代码的较短版本,以便读者可以理解做什么。

My Problem: The function below opens a text file and searches for numbers placed at a specific place inside the text file.The numbers(I used ID in the code) start from 1 to 25000 and there are a few that are missing(for example there's no life 25,but 24,23,26,27 etc). 我的问题:下面的函数将打开一个文本文件并搜索放置在文本文件中特定位置的数字。数字(我在代码中使用ID)从1到25000开始,并且缺少一些数字(例如没有生命25,但有24、23、26、27等)。 I want the code to copy the lines in the array "Ids".Its not meant to be an array,I'm just new and I don't know if anything else would be more handy for LINQ. 我希望代码复制“ 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);
                }

            }
        }
    }

What it writes: It only writes one line with number ,which is the first member of the Ids[] array(14652). 它写的是:它只写一个带数字的行,它是Ids []数组的第一个成员(14652)。

I had to add the second 'from' ,which is placed at first place in the code so it will check it for every member of the array.I get the from statement as a "while",because I couldn't find a snipper with normal code-> linq. 我必须添加第二个“ from”,它位于代码的第一位,因此它将检查数组的每个成员。我将from语句作为“ while”来获取,因为我找不到快照程序用正常的代码-> LINQ。

Where is the problem in the code? 代码中的问题在哪里?

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

You can tweak the Contains with ? 您可以使用调整“包含”吗? to get around splits that don't have an item at 1. 绕过没有1项的拆分。

Is this what you're trying to do? 这是您要做什么? I think the second from is like a cross join which Isn't necessary as I understand your problem. 我认为第二点就像是交叉连接,因为我了解您的问题,所以这不是必需的。

It only writes one line with number ,which is the first member of the Ids[] array(14652). 它只写一个带数字的行,它是Ids []数组的第一个成员(14652)。 Where is the problem in the code? 代码中的问题在哪里?

from id in Ids
from line in ReadLines(reader)

This code is conceptually like (ignoring deferred execution): 这段代码在概念上类似于(忽略延迟执行):

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

Which will work great for the first id, but then the reader will be at the end of the file for the second id on and no matches will be found. 这对于第一个ID会非常有用,但随后读者将在文件的末尾找到第二个ID,并且找不到匹配项。

This code is untested, but are you looking for something like this? 该代码未经测试,但是您是否正在寻找类似的东西?

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;

You need to perform a join, as if you were joining two tables. 您需要执行联接,就像要联接两个表一样。 Thinking about the process from the standpoint of a SQL query...you have two tables...Ids and Lines. 从SQL查询的角度考虑流程...您有两个表... Id和Lines。 Lines has two fields, Id and Line, and needs to be inner joined to the Ids table. Lines有两个字段,Id和Line,需要内部连接到Ids表。 You can accomplish this with the following LINQ query: 您可以使用以下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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM