2016-12-12 17 views
1

我正在努力與列表內的列表。有幾個問題。如何在列表中的幾個arraylist之一中找到一個字符串元素? C#

首先:我的移除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. 
     } 
    } 
+0

情況4中應該發生什麼異常? – XtremeBaumer

回答

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; 
    } 
} 

請注意,有這個代碼的結構改進的餘地。

+0

Thx Petter,我會嘗試一下,一進杯咖啡就開始工作,從早上起我一直在這裏工作,我會讓你知道結果 – Tarbh

+0

我已經試過了,它工作得很好,我慢慢的學習了這一點,只有9個星期了)Thx尋求幫助。 – Tarbh

+0

Lykke til videre。 –

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."); 
    } 
} 
+0

Thx幫助,但爲什麼我 - - ; ?? – Tarbh

+0

i--補償刪除元素。 –

+0

啊,好吧.....這真的解釋了我以前的例外,thx – Tarbh

0

嘗試removeall過改用:

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

List.RemoveAll Method @ MSDN

+0

如果(說)後#5有一個帖子正文值爲「日誌號:2」,它將被刪除與實際#2一起。 'x [0] .Contains(erase)'會更好。 –

+0

我無法從問題中找到此要求。如果x是空的,那麼代碼將失敗。 – Chrille

0

正如其他人所指出的那樣,你不能當你迭代它與修改工作日誌收集的foreach。您可以使用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; 
    } 
} 
+0

有幾個問題:請理解我在編碼方面是新的,但是「logBook [i] [0]」究竟是指什麼(它究竟是什麼意思呢?我相信我有一個包含Array [](type string)的元素,它又包含4個字符串元素(logNR,timeDate,post和title),所有這些都像一棵樹(我試圖去獲得它的邏輯) 爲什麼我們會盡快回復您的問題 Thx幫助 – Tarbh

相關問題