【问题标题】:Loop through list, match word call description from list循环遍历列表,匹配列表中的单词调用描述
【发布时间】:2013-11-23 13:53:03
【问题描述】:

我在构建循环时遇到问题,该循环会将 VAR(userSelection) 与我的 LIST(Listings) 中的名称 ITEMS 进行比较。目标是如果userSelection MATCHES 名称,getDescription 将Console.WriteLine 中的GetDefinition 并显示列表中匹配的单词的定义。我的大部分代码都在工作,我已经为这个任务工作了一周。

我是个新手,请假设我一无所知。感谢所有帮助。我认为这将是一个while循环,但我现在已经玩过所有循环并且迷失和困惑。我是新手,请用小字,尽可能详细。非常感谢。谢谢。

我的 C# 程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading.Tasks;// Needed for Streaming...
using System.IO;// Needed for Streaming...

namespace a090___StreamReader_DictionarySearch
{
class Program
{
    private const String FILE_NAME = "dictionary.txt";//establish text file instance

    public void Play()
    {
        do
        {
            DisplayTitle();

            List<Listing> items = LoadListings();//create a list of WordDef objects

            Console.Write(string.Join(" | ", items.Select(x => x.GetName()))); //Console.Write("\b \b");// Backspace would also of worked


            DisplayText("\n\nPlease enter a word from the selections about to see it's definition");// Nice use of PROMPT
            String userSelection = Console.ReadLine().ToLower();//Capture input

            //loop through all of the listings, and compare each one to userSelection
            //Then once it equals print definition

            bool found = false;

            foreach (Listing item in items)
            {
                if (userSelection == item.GetName())
                {
                    Console.WriteLine("You selected: " + userSelection +
                                "\nWhich Means: " + item.GetDefinition());
                    found = true;
                    break;
                }
            }

            if (!found)
            { Console.WriteLine("I'm sorry, I don't have a match for that."); }

        } while (PlayAgain());

        Salutation();
    }

    //ToolBox -- my program specific tools
    public List<Listing> LoadListings()//load entries display as list
    {
        StreamReader fileIn = new StreamReader(FILE_NAME);
        List<Listing> entry = new List<Listing>();

        //loop through every line of the file
        while (!fileIn.EndOfStream)
        {
            String line = fileIn.ReadLine();
            String[] pieces = line.Split(':');

            if (pieces.Length < 1) continue;//error handling - set to length of text items

            Listing myListing = new Listing(pieces[0], pieces[1]);
            entry.Add(myListing);
        }
        fileIn.Close(); return entry;
    }




    //MaxBox -- my useful tools
    public void DisplayText(String StringNameIs)
    { Console.WriteLine(StringNameIs); }//Where are we?

    public Boolean PlayAgain()
    {
        Console.Write("\n\nDo you select again? (y)es or (n)o: ");
        String command = Console.ReadLine().ToLower();

        if (command == "y" || command == "yes") return true;
        return false;
    }

    public void Salutation()
    { Console.Clear(); Console.WriteLine("Ti Do - oh - oh Ti Do -- So Do!"); } //The last line from the 'do-re-mi' song from the Sound of Music

    public void DisplayTitle()
    { Console.Clear(); Console.WriteLine(">>>-- A Dictionary of Sounds --<<< \n"); } //Announce Our Program  



    static void Main(string[] args)
    {
        Program DictionaryLookup = new Program();
        DictionaryLookup.Play();
        Console.Read();
    }
}
}

我的班级

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace a090___StreamReader_DictionarySearch
{
class Listing
{
    private String name;
    private String definition;

    public Listing(String name, String definition)
    { this.name = name; 
      this.definition = definition;}

    public String GetName()       {return name;}
    public String GetDefinition() {return definition; }
}
}

我的文本文件

Doe: a deer, a female deer
Ray: a drop of golden sun
Me: a name I call myself
Far: a long, long way to run
Sew: a needle pulling thread
La: a note to follow Sew

茶:加果酱和面包的饮料

【问题讨论】:

  • 如果我这样做了,你怎么知道问题不是来自我可能删除的其他方面之一?
  • 明白,谢谢。会尽量记住这一点(这有助于理解 - 我认为对于这个我应该在使用 Streamer 时显示名称空间。

标签: c# list loops streamreader


【解决方案1】:

这是未经测试的,但应该可以使用您现有的代码。

假设每个“名称”(doe、ray 等)只出现一次(它们确实如此),那么您可以使用 Linq 的“SingleOrDefault”,如果找不到匹配项,它将返回 null

var selection = items.SingleOrDefault(x => x.GetName() == userSelection);

if (selection == null)
    Console.WriteLine("I'm sorry, I don't have a match for that.");
else
    Console.WriteLine("You selected: " + userSelection +
                      "\nWhich Means: " + selection.GetDefinition());

要在比较过程中忽略大小写,请尝试修改上述内容:

... items.SingleOrDefault(x => String.Compare(x.GetName(), userSelection, true));

您可以在此处更改许多其他内容,但也许这对您的分配无关紧要。例如,我会删除 Listing 类中的私有变量并将公共“get”方法更改为属性:

public String Name { get; private set; }
public String Definition { get; private set; }

【讨论】:

  • 我试过这个,但它总是返回未找到的答案:if (items.Select(x => x.GetName()).Contains(userSelection)){var selection = items.Single(x => x.GetName() == userSelection); Console.WriteLine("你选择了:" + userSelection + "\n这意味着:" + selection.GetDefinition()); } else { Console.WriteLine("对不起,我没有匹配的。"); }
  • 查看上面的示例,我意识到添加 '.ToLower()' 使其工作。所以在我尝试步进之后(关于如何为 express 做的说明确实让我感到困惑,我不知道我做对了 - 我在运行 Visual Studio 的 Mac 上)。我在提到“x.GetName()”的两个地方都添加了“.ToLower()”。所以我认为问题在于比较不同情况下的变量 - 我在 Sentence case 中输入,将其调低,但列表仍然是标题大小写。这样做使它工作。那是正确的做法吗?感谢您的学习体验 - 非常感谢
  • 在 LINQ 查询中选择名称 (GetName()),然后检查 Contains,然后选择 Single,这是一种浪费的开销。整个查询可能是:items.SingleOrDefault(x =&gt; x.GetName() == userSelection),然后检查结果是否为Null
  • 什么是 LINQ 查询?这个对话是我第一次听说。同样,我没有/不知道比较选项。我是超级新手,有点我不想成为。感谢您提供所有信息和指导。
  • LINQ 听起来很有趣。我期待在未来深入研究它。现在,我计划坚持掌握循环、方法和数组,然后再学习类等经过验证的真实路径。
【解决方案2】:

替换代码

while (true)
            {
                if (userSelection == name)
                {Console.WriteLine("You selected: " + Listing.userSelection() +
                                "\nWhich Means: " + Listing.items.GetDefinition());}
            }
           else { Console.WriteLine("I'm sorry, I don't have a match for that."); }

有了这个

        bool found = false;

        foreach (Listing item in items)
        {
            if (userSelection == item.GetName().ToLower())
            {
                Console.WriteLine("You selected: " + userSelection +
                            "\nWhich Means: " + item.GetDefinition());
                found = true;
                break;
            }
        }


        if (!found)
        { Console.WriteLine("I'm sorry, I don't have a match for that."); }

我使用了foreach 语句;使用此语句,您可以迭代集合中的所有项目。

在 foreach 循环中,我检查元素名称是否与用户输入相同,如果匹配,我设置一个布尔变量来指示找到的元素。

如果未找到元素,则在循环后打印消息。

NB 显然这段代码可以用 LINQ 写得更简洁。

【讨论】:

  • 我尝试了这个解决方案,它没有错误,非常好。但它总是返回 !found 答案。我尝试使用 Doe 和 doe 进行测试,两次返回的响应都是 !found。我认为我做错了什么 - 我已经更新了我的代码以反映我如何尝试实施您的解决方案 Max。
  • 我已经更新了代码。我在 foreach 中添加了 ToLower() 这是因为 userSelection 被“降低”了。我建议将 ToLower() 删除到这两个地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
相关资源
最近更新 更多