【问题标题】:Second "from" statement in LINQLINQ 中的第二个“from”语句
【发布时间】:2010-10-28 06:55:15
【问题描述】:

我是 LINQ 的新手,我对该库的了解来自 Jon Skeet 的《C# In Depth 1》一书

在过去的几天里,我阅读了很多关于 LINQ 的教程,包括 Skeet 的书,但我从来没有找到显示普通 C# 代码的代码 sn-p 以及带有 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”,因为我不能用普通代码找到一个snipper-> linq。

代码哪里出了问题?

【问题讨论】:

    标签: c# linq


    【解决方案1】:
    from line in ReadLines(reader)
    where Ids.Contains(line.Split('\t')[1])
    select line;
    

    您可以使用 ? 调整包含绕过在 1 处没有项目的拆分。

    这是你想要做的吗?我认为第二个来自就像一个交叉连接,因为我理解你的问题,这不是必需的。

    【讨论】:

      【解决方案2】:

      此代码未经测试,但您是否正在寻找类似的东西?

      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】:

        它只写一行数字,这是 Ids[] 数组 (14652) 的第一个成员。 代码哪里出了问题?

        from id in Ids
        from line in ReadLines(reader)
        

        此代码在概念上类似于(忽略延迟执行):

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

        这对第一个 id 非常有用,但随后阅读器将在文件末尾找到第二个 id 并且找不到匹配项。

        【讨论】:

          【解决方案4】:

          您需要执行连接,就像连接两个表一样。从 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;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-04
            • 1970-01-01
            • 1970-01-01
            • 2018-09-26
            • 2015-12-31
            相关资源
            最近更新 更多