如何在列表中的几个arraylists之一中找到一个字符串元素? C#

时间:2016-12-12 13:42:26

标签: c# list search edit

我正在与列表中的arraylists斗争。有几个问题。

首先:我删除logg的试验工作正在进行,但是我触发了异常,不知道该怎么做(见案例4)。

第二:我想能够编辑任何现有的日志(不在菜单中),更像是更改现有日志中的一个字符串,如“post”或“title”。任何人都可以给我提示??

{
    List<string[]> logBook = new List<string[]> { }; // Skapar en lista för arrayer av typen string.
    DateTime time = DateTime.Now;  // Sätter variabeln time till lokal tid på datorn.

    int logCount = 0;  // Deklarerar en variabel för att räkna inläggen,
                       // läggs utanför case 1 så att den är nollad vid uppstart av programmet 
                       // och när den kommer in i case 1 så räknar den upp.

    Console.WriteLine("\t" + time.ToLongDateString()); // Skriver ut datum i ett passande format för en loggbok.
    Console.WriteLine("\n\tWelcome to the Logbook!\n");  // Skriver ut välkomsttext en gång vid uppstart,
                                                         // därför läggs den utanför while-loopen.

    bool go = true; // Booleanskt värde för while-loopen som ska ligga för menyn och som br

    while (go)
        try         // Exception-block som fångar upp om användaren knappar in ex. bokstäver som val i menyn (förhindrar körfel).
        {
            {
                Console.WriteLine("");  //Skapar ny rad. Användaren ska inte känna att det blandar ihop sig.
                Console.WriteLine("\t[1] Write a new post");
                Console.WriteLine("\t[2] Search for a post");
                Console.WriteLine("\t[3] Display all posts");
                Console.WriteLine("\t[4] Remove a post");
                Console.WriteLine("\t[5] Quit");

                Console.Write("\n\tSelect from menu: ");

                int menu = Convert.ToInt32(Console.ReadLine());  //Gör om inmatad sträng till heltal.
                Console.WriteLine("");  //Skapar mellanrum innan nästa direktiv till användaren (Estetiskt).

                switch (menu)
                {
                    case 1:

                        logCount++;
                        string logNr = "Log number: " + logCount.ToString();  // Skapar en nurering av loggarna.

                        string timeDate = time.ToLongDateString();  // Ger oss ett datum för inlägget.

                        Console.Write("\tWrite a title to your post: ");
                        string title = "Title: " + Console.ReadLine();  // Ger oss en titel för inlägget.

                        Console.Write("\n\tPost is created " + timeDate + "\n\n\tWrite your post: ");

                        string post = Console.ReadLine();

                        string[] arr = new string[4];
                        arr[0] = logNr;  
                        arr[1] = timeDate;
                        arr[2] = title;
                        arr[3] = post;

                        logBook.Add(arr);
                        break;

                    case 2:
                        Console.Write("\tWrite a searchword or a date (yyyy-mm-dd): ");
                        string keyword = Console.ReadLine();
                        Console.WriteLine("");

                        bool anyFound = false;

                        foreach (string[] item in logBook)  //För varje element(item) i Listan(logBook) dvs (arr[i])
                        {
                            foreach (string element in item)  //För varje element(element) i arr[i] dvs (arr[0], arr[1], arr[2])
                            {
                                if (element.Contains(keyword))  // Om arr[0], arr[1] eller arr[2] innhåller sökord....,
                                                                // letar efter en substring(keyword) inom strängen.
                                {
                                    foreach (string s in item)  // Skriv ut varje arr[i] i det elementet(item) (dvs hela den loggen)
                                                                // I detta fall tre varv, datum, titel, text(post) = 3 strängar.
                                                                // För att användaren ska kunna se hela loggen som sökordet finns i.
                                    {
                                        Console.WriteLine("\t" + s);
                                    }
                                    Console.WriteLine("");
                                    anyFound = true;  // Kliver ur loopen då uppdraget är slutfört, bool ändrar värde till true.
                                }
                            }
                        }
                        if (!anyFound)  // Om inget hittas dvs bool är fortfarande oförändrat genomförs utskrift.
                            Console.WriteLine("\tSearchword couldn't be found.");
                        break;

                    case 3:
                        Console.WriteLine("\tThese are the current posts in Logbook.\n ");

                        foreach (var item in logBook)  //För varje element(item) i Listan(logBook) dvs (arr[i])
                        {
                            foreach (string element in item)  //För varje element(element) i arr[i] dvs (arr[0], arr[1], arr[2])
                            {
                                Console.WriteLine("\t" + element);
                            }
                                Console.WriteLine("");
                        }
                        break;

                    case 4:

                        Console.Write("\tWhich log number do you want to remove? : ");
                        string erase = "Log number: " + Console.ReadLine();

                        foreach (string[] item in logBook)  // För varje element(item) i Listan(logBook) dvs (arr[i])
                        {
                            if (item.Contains(erase))  // Om arr[0], arr[1] eller arr[2] innhåller sökord....,
                            {
                                logBook.Remove(item);  // raderas hela elementet(item/arr[i])
                                Console.WriteLine("\t" + erase + " is now removed from logbook.");
                            }
                        }


                        break;

                    case 5:
                        go = false; // Avbryter while-loopen och med det avslutar programmet.
                        break;

                    default:        // Fångar upp om användaren skriver in ett tal utanför valmenyn.
                        Console.WriteLine("\tChoose from menu 1 - 4");
                        break;
                }
            }
        }
        catch(Exception e)
        {
            Console.WriteLine("");  //Estetisk för att användaren ska få ny rad innan meddelandet.
            Console.WriteLine("\tChoose from menu by using number 1 - 4\n" + e); //Aktiveras om användaren knappar in annat än heltal.
        }
    }   

4 个答案:

答案 0 :(得分:1)

在foreach中迭代列表时,无法修改列表。来自MSDN

  

foreach语句用于遍历集合以获取所需的信息,但不能用于在源集合中添加或删除项以避免不可预测的副作用。如果需要在源集合中添加或删除项目,请使用for循环。

你可以考虑使用for循环而不是foreach吗?有点像:

for (var i = 0; i < logbook.Count; i++)
{
    if (logbook[i].Contains(erase))
    {
        logBook.RemoveAt(i);
        i--;
        Console.WriteLine("\t" + erase + " is now removed from logbook.");
    }
}

答案 1 :(得分:0)

尝试使用RemoveAll:

logBook.RemoveAll(log => log.Any(row => row.Contains(erase)));

List.RemoveAll Method @ MSDN

答案 2 :(得分:0)

正如其他人所指出的那样,当您使用foreach迭代它时,无法修改logBook集合。您可以使用for循环在列表中向后工作,并在找到要查找的帖子时使用RemoveAt。

看到最多只有一个具有给定日志编号的帖子,您还应该在循环中包含一个中断,以便在找到并删除帖子后退出。像这样:

for (var i = logBook.Count - 1; i >= 0; i--)
{
    if (logBook[i][0] == erase)
    {
        logBook.RemoveAt(i);
        Console.WriteLine("\t" + erase + " is now removed from logbook.");
        break;
    }
}

答案 3 :(得分:0)

@ScottPerham是正确的,你不能在迭代时修改它。由于您可能只想删除一个项目,因此您还可以在删除项目后通过简单地break来解决这个问题。

这一行存在问题:

if (item.Contains(erase))

item是一个字符串数组;调用的Contains方法是集合上的一个方法,它检查集合中的任何元素是否与提供的输入完全匹配。这与查找子字符串的string.Contains不同。你想要这个:

if (item[0].Contains(erase))

修改

鉴于您的搜索字符串应该是完全匹配,您应该找到帖子 - 但您也会找到帖子正文的任何​​帖子,例如“日志编号:2”(可能是不同的后)。你真的只想检查ítem[0]

回答你的第二个问题:你已经知道如何找到一个帖子;你这样做是为了“删除”案件。找到想要更改的内容后,只需更新内容,类似于创建新帖子时的内容:

Console.Write("\tWhich log number do you want to change? : ");
string change = "Log number: " + Console.ReadLine();

foreach (string[] item in logBook)  // För varje element(item) i Listan(logBook) dvs (arr[i])
{
    if (item[0].Contains(change))  // Om arr[0], arr[1] eller arr[2] innhåller sökord....,
    {
        string timeDate2 = time.ToLongDateString();  // Ger oss ett datum för inlägget.

        Console.Write("\tWrite a title to your post: ");
        string title2 = "Title: " + Console.ReadLine();  // Ger oss en titel för inlägget.

        Console.Write("\n\tPost is created " + timeDate2 + "\n\n\tWrite your post: ");

        string post2 = Console.ReadLine();

        item[1] = timeDate2;
        item[2] = title2;
        item[3] = post2;
    }
}

请注意,此代码的结构仍有改进的余地。