首页 > 解决方案 > C# 在 tsv 文件中的列表中查找文本

问题描述

我正在尝试解决 codeacademy 项目中的一项任务,该任务是在 tsv 文件中找到一个单词,该文件由以下代码组成:

List<Language> languages = File.ReadAllLines("./languages.tsv")
        .Skip(1)
        .Select(line => Language.FromTsv(line))
        .ToList();

我尝试了以下方法并收到错误 CS1929:

var ChiefDeveloperMS = languages.Where(chief => $"{chief.Contains("Microsoft")}");

foreach (var d in ChiefDeveloperMS)
        {
          Console.WriteLine($"{d.Prettify()}");
        }

我要找的词是微软。

Prettify 是语言类中的一个方法,代码如下:

public string Prettify()
    {
      return $"{Year}, {Name}, {ChiefDeveloper}, {Predecessors}";
    }

来自 tsv 文件的示例:

Year    Name    Chief developer, company    Predecessor(s)
1991    Visual Basic    Alan Cooper (sold to Microsoft) QuickBASIC
2001    GDScript(GDS)   OKAM Studio Godot
2001    Shakespeare Programming Language    Jon Åslund, Karl Hasselström    none
2002    Io  Steve Dekorte   Self,NewtonScript,Lua
2002    Gosu    Guidewire Software  GScript
2005    F#  Don Syme (Microsoft Research)   OCaml,C#,Haskell

我在控制台中得到的输出:

1996, VBScript, Microsoft, Visual Basic
2001, Visual Basic .NET, Microsoft, Visual Basic
2006, Windows PowerShell, Microsoft, C#,ksh,Perl,CL,DCL,SQL

预期输出:

1991    Visual Basic    Alan Cooper (sold to Microsoft) QuickBASIC
1996    VBScript    Microsoft   Visual Basic
2000    C#  Anders Hejlsberg (Microsoft, ECMA)  C,C++,Java,Delphi,Modula-2
2001    Visual Basic .NET   Microsoft   Visual Basic
2005    F#  Don Syme (Microsoft Research)   OCaml,C#,Haskell
2006    Windows PowerShell  Microsoft   C#,ksh,Perl,CL,DCL,SQL

我尝试了很多变体,在 codeacademy facebook 组上搜索并询问,但仍然找不到答案,正确的命名空间在 progam.cs 的顶部。

昨天我通过解决方法获得了有关 stackoverflow 的帮助,它以某种方式工作,但问题是它不会打印控制台上 tsv 文件中括号中的单词。

这是解决方法代码:

var ChiefDeveloperMS = languages.Where(chief => chief.ChiefDeveloper == "Microsoft");

语言类的构造函数:

public Language(int year, string name, string chiefDeveloper, string predecessors)
    {
      Year = year;
      Name = name;
      ChiefDeveloper = chiefDeveloper;
      Predecessors = predecessors;
    }

我不明白为什么 .Contain() 方法在我多次以类似方式成功使用时不起作用。

我应该放弃这个然后再回来吗?这对初学者来说复杂吗?

我是新来的,如果需要更多信息,我很乐意编辑我的帖子。

标签: c#linq

解决方案


那么,为什么会这样:

var ChiefDeveloperMS = languages.Where(chief => $"{chief.Contains("Microsoft")}");

不起作用是因为一切都搞砸了

哪里是一个 LINQ 命令,它希望您将一个函数传递给它,该函数返回一个布尔值(或计算结果为布尔值的表达式和

chief => $"{chief.Contains("Microsoft")}"

不是导致布尔值的表达式。我会把它拆开,这样你就知道出了什么问题

  • chief =>为将传递给表达式/函数的列表元素命名。您在 Language 对象列表中调用 Where ,因此调用它lang会比首席更好。chief是(/lang将是)一个语言对象。如果你想获得它的 ChiefDeveloper 属性,你必须说chief.ChiefDeveloper-> 你能明白为什么我建议查看对象集合并选择一个可以很好地为集合中的项目提供单一引用的名称吗?lang.ChiefDeveloper更有意义,chief.ChiefDeveloper并且可以帮助您将正在使用的内容保持在头脑中

  • $"开始一个内插字符串

  • {在插值字符串内标记被评估字段的开始

  • chief.Contains("Microsoft")是个问题。包含询问一个字符串是否包含另一个字符串,但请记住,您chief是一个语言对象,而不是一个字符串。语言没有 Contains 方法。如果确实如此,它将返回 true 或 false,这将通过插值过程合并到字符串中,您最终会得到以下字符串之一:

    “真假”

这些不是布尔值。它们是包含我们在谈论布尔值时常用的单词但它们不是布尔值的字符串,“1234”不是数字或时间,“04-09-2000”不是日期。这些都是字符串,不管你的大脑在看到它们时会识别和解释什么(哦,4 月 9 日还是 9 月 4 日?)

把所有这些放在一起,正确命名我们的集合,很好地命名我们的表达式输入变量,确保它返回一个布尔值......

var msLangs = allLangs.Where(lang => lang.ChiefDeveloper.Contains("Microsoft"));

您现在可以迭代并打印它们:

    foreach (var msLang in msLangs)
    {
      Console.WriteLine(msLang.Prettify());
    }

注意我保持明智的命名 - 集合有复数名称

  • msLangs:微软语言的集合
  • msLang:上述命名集合项之一

您不需要将 msLang.Prettify 放在插值字符串中。Prettify 已经返回了一个字符串。将其包装在一个不包含其他内容的内插字符串中是一种浪费的操作

我还想指出 prettify 不会以您说要输出的格式返回字符串。Prettify 添加逗号

因为可以公平地说您对问题的说明并没有像它本来应该的那样准确,所以我不确定是否要解决最后一点。要么修改你的美化,让它发出制表符而不是逗号,要么绕过美化并自己插入一个字符串。

我想提出的另一个(也是最后一点)一点是,软件工程师按照规范工作,规范必须绝对准确、完整、全面等。希望这整个体验对你来说是值得的,因为一开始你的规范很糟糕; 它根本无法实施 - 这是你的老板会放在你的办公桌上并期望你做的半生不熟的事情,如果你这样做并假设等等,你最终会给他一些他没有的东西'不想要。在与其他软件开发人员交谈时,请始终注意规范的准确性和完整性。总是,当收到某人的规格时,要求相同..否则它将是“垃圾进,垃圾出”


推荐阅读