我正在与列表中的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.
}
}
答案 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)));
答案 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;
}
}
请注意,此代码的结构仍有改进的余地。