Permalänk

Sökning i c#

Hej, jag är helt ny inom ämnet och går programmering 1. I den projektuppgift jag har så ska jag skapa en blogg med lite olika funktioner. Jag får dock inte till sökfunktionen i bloggen. När jag söker på nya inlägg som jag skrivit så hittar den aldrig nått. När jag söker på gamla inlägg så får jag alltid två svar. Hittat och inte hittat. Jag hoppas nån här kan hjälpa mig.

static void Main(string[] args) { //Här är listan List<string[]> minaInlägg = new List<string[]> { }; //inläggen string[] inlägg01 = new string[2]; inlägg01[0] = "Nu skriver jag bloggens första titel"; inlägg01[1] = "Nu skriver jag bloggens första inlägg"; minaInlägg.Add(inlägg01); //skickar inläggen till listan string[] inlägg02 = new string[2]; inlägg02[0] = "Nu skriver jag bloggens andra titel"; inlägg02[1] = "Nu skriver jag bloggens andra inlägg"; minaInlägg.Add(inlägg02); string[] inlägg03 = new string[2]; inlägg03[0] = "Nu skriver jag bloggens tredje titel"; inlägg03[1] = "Nu skriver jag bloggens tredje inlägg"; minaInlägg.Add(inlägg03); //Här deklarerar jag sökordet som används senare string sökOrd = (""); string sökOrdTvå = (""); //bool och while, bool är true för att programmet ska avslutas när användaren väljer false bool progRun = true; //while loop som gör att menyn visas tills användaren väljer att avsluta while (progRun) { Console.Clear(); //inläggen string[] inlägg = new string[2]; Console.WriteLine("\n\tHuvudmeny!"); //Menyval Console.WriteLine(" "); Console.WriteLine("\n\t[1]Skriv nytt inlägg"); Console.WriteLine("\n\t[2]Sök inlägg i bloggen"); Console.WriteLine("\n\t[3]Se alla inlägg"); Console.WriteLine("\n\t[4]Avsluta"); //Sparar användarens val och kör tryparse för att förhindra att programmet crashar om användaren t.ex skulle slå in en bokstav. int valEtt; Int32.TryParse(Console.ReadLine(), out valEtt); //För att ta bort allt som användaren redan valt och göra det mindre rörigt. Console.Clear(); //switch loop switch (valEtt) { //Menyval 1, användaren skriver ett nytt inlägg case 1: string[] nyttInlägg = new string[2]; //Val av titel Console.WriteLine("Ange titel"); //Sparar titeln i index 0 nyttInlägg[0] = Console.ReadLine(); //Användaren skriver inlägget Console.WriteLine("Skriv inlägg"); //Sparar inlägget i index 1 nyttInlägg[1] = Console.ReadLine(); //Frågar användaren om hen vill spara inlägget Console.WriteLine("Spara inlägg?"); Console.WriteLine("[1]Ja / [2]Nej"); //Tryparse för att förhindra crash int spara; Int32.TryParse(Console.ReadLine(), out spara); //if loop vid som beror på användarens val if (spara == 1) { //sparar inlägget Console.WriteLine("\n\tInläggget har sparats"); minaInlägg.Add(nyttInlägg); } else { //inlägget sparas inte Console.WriteLine("\n\tInlägget sparades inte"); } break; case 2: Console.WriteLine("[1]Sök efter titlar"); Console.WriteLine("[2]Sök efter inlägg"); int valTvå; Int32.TryParse(Console.ReadLine(), out valTvå); if (valTvå == 1) { Console.Write("Ange sökord: "); sökOrdTvå = Console.ReadLine(); for (int i = 0; i < minaInlägg[0].Length; i++) { //Om sökningen träffar eller inte if (minaInlägg[i][0].Contains(sökOrdTvå)) // sökning i index 0 { Console.Clear(); //träff Console.WriteLine("\n\tDin sökning träffade en titel: " + sökOrdTvå); Console.ReadLine(); } else { Console.Clear(); Console.WriteLine("\n\tDin sökning träffade tyvärr inte en titel"); Console.ReadLine(); } } } else if (valTvå == 2) { //användaren anger vad hen vill söka efter Console.Write("Ange sökord: "); //sökordet får ett värde sökOrd = Console.ReadLine(); //sökningen for (int i = 1; i < minaInlägg[i].Length; i++) { //Om sökningen träffar eller inte if (minaInlägg[i][1].Contains(sökOrd)) // sökning i index 0 { Console.Clear(); //träff Console.WriteLine("\n\tDin sökning träffade ett inlägg " + sökOrd); Console.ReadLine(); } else { Console.Clear(); Console.WriteLine("\n\tDin sökning träffade tyvärr inte ett inlägg"); Console.ReadLine(); break; } } } else { Console.WriteLine("\n\tOgiltligt val"); } break; case 3: foreach (var item in minaInlägg) { Console.WriteLine("\n\tTitel: " + item[0]); // Skriver ut resultet för sökningen Console.WriteLine("\n\tInlägg: " + item[1]); Console.WriteLine(" "); } Console.ReadLine(); break; //Programmet avslutas när användaren väljer 4 case 4: progRun = false; break; //Användaren har gjort ett ogiltigt val default: Console.WriteLine("\n\tAnvänd siffrorna 1-4"); break; } } //Hej då hälsning Console.WriteLine("\n\tTack för den här gången"); //För att programmet ska visa hej då hälsningen så används en readline. Console.ReadLine();

Permalänk
Hedersmedlem

Hej!

Det är lite svårt att läsa din kod och följa med eftersom formumet tar bort kodindentering. För att lösa det, redigera ditt inlägg och skriv [code] före och [/code] efter koden.

Men utifrån vad jag kan förstå av koden utan indentering så gissar jag att ditt problem är att du skriver ut "jag hittade ingen träff" varje gång du kollar i varje inlägg. D.v.s om dina titlar är:

ost
prost
roquefort
sydost

Och du söker efter ost så kommer den typ skriva ut:

Hittade ost i "ost"
Hittade ost i "prost"
Åh nej, hittade inte "ost" i "roquefort"
Hittade ost i "sydost"

Finns olika sätt att lösa detta, enklaste är en flagga som du sätter "hittade något" som du sätter till true när du hittar något, och endast skriver ut "hittade inget" om denna flagga är false.

Ett allmänt tips: Det blir lättare att följa din kod om du gör separata funktioner för varje menyval.

Permalänk
Medlem

Här är en idé:

// Ändra: for (int i = 0; i < minaInlägg[i].Length; i++) // Till: for (int i = 0; i < minaInlägg.Length; i++)

D.v.s. ta bort [i]. Du vill loopa över inläggen, men som koden är nu blir det i praktiken i < 2 (eftersom alla inlägg har två fält, om jag fattat allt rätt). Därefter tror jag du kommer stöta på problemet som pv2b nämnde.

Permalänk
Skrivet av pv2b:

Hej!

Det är lite svårt att läsa din kod och följa med eftersom formumet tar bort kodindentering. För att lösa det, redigera ditt inlägg och skriv [code] före och [/code] efter koden.

Men utifrån vad jag kan förstå av koden utan indentering så gissar jag att ditt problem är att du skriver ut "jag hittade ingen träff" varje gång du kollar i varje inlägg. D.v.s om dina titlar är:

ost
prost
roquefort
sydost

Och du söker efter ost så kommer den typ skriva ut:

Hittade ost i "ost"
Hittade ost i "prost"
Åh nej, hittade inte "ost" i "roquefort"
Hittade ost i "sydost"

Finns olika sätt att lösa detta, enklaste är en flagga som du sätter "hittade något" som du sätter till true när du hittar något, och endast skriver ut "hittade inget" om denna flagga är false.

Ett allmänt tips: Det blir lättare att följa din kod om du gör separata funktioner för varje menyval.

Så ja. Tror det blev som du menade nu.
Jag tror inte att det är problemet. Om jag söker på t.ex andra så finns det ju bara en titel och ett inlägg med ordet andra. Om jag förstod dig rätt.

Permalänk
Skrivet av lydell:

Här är en idé:

// Ändra: for (int i = 0; i < minaInlägg[i].Length; i++) // Till: for (int i = 0; i < minaInlägg.Length; i++)

D.v.s. ta bort [i]. Du vill loopa över inläggen, men som koden är nu blir det i praktiken i < 2 (eftersom alla inlägg har två fält, om jag fattat allt rätt). Därefter tror jag du kommer stöta på problemet som pv2b nämnde.

Jag kunde inte skriva utan [] i for loopen. Menar du att jag ska lämna de tomt?

Edit: Det fick jag inte heller göra märkte jag nu.

Permalänk
Medlem
Skrivet av YourHonour:

Jag kunde inte skriva utan [] i for loopen. Menar du att jag ska lämna de tomt?

Edit: Det fick jag inte heller göra märkte jag nu.

Vad betyder ”kunde inte”? Det är alltid bättre att vara exakt när man frågar om programmering, för allt handlar om detaljer i slutändan.

Och det stämmer att jag menade ta bort det helt, inte lämna tomt.

Jag kan inte C#, men det kan vara så att du behöver använda .Count istället för .Length när man har en List (som minaInlägg verkar vara). Eller en foreach. Källa: https://stackoverflow.com/questions/18863187/how-can-i-loop-through-a-listt-and-grab-each-item

Permalänk
Medlem
Skrivet av YourHonour:

Jag kunde inte skriva utan [] i for loopen. Menar du att jag ska lämna de tomt?

Edit: Det fick jag inte heller göra märkte jag nu.

Det fungerar inte eftersom minaInlägg är en List<string[]> medan minaInlägg[i] är en string[], och C# har av någon anledning olika sätt att ta reda på längden beroende på om det är en s.k. "Collection" (som t.ex. List) eller en array.

Längden av en List får man därför med Count istället för Length, d.v.s. minaInlägg.Count för att få längden på listan eller minaInlägg[i].Length för att få längden på en specifik array i listan.

Ja, det är ganska idiotiskt, men det finns säkert någon obskyr teknisk anledning till att de valt att göra så

Permalänk
Medlem
Skrivet av perost:

Det fungerar inte eftersom minaInlägg är en List<string[]> medan minaInlägg[i] är en string[], och C# har av någon anledning olika sätt att ta reda på längden beroende på om det är en s.k. "Collection" (som t.ex. List) eller en array.

Längden av en List får man därför med Count istället för Length, d.v.s. minaInlägg.Count för att få längden på listan eller minaInlägg[i].Length för att få längden på en specifik array i listan.

Ja, det är ganska idiotiskt, men det finns säkert någon obskyr teknisk anledning till att de valt att göra så

Det har att göra med att Collections är dynamiska medan Array är statisk. Count antyder att vi kommer att iterera igenom kollektionen och räkna antalet element, medan Length är ett statiskt värde som kan återges direkt.

Semantik

Visa signatur

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

Permalänk
Medlem
Skrivet av noMad17:

Det har att göra med att Collections är dynamiska medan Array är statisk. Count antyder att vi kommer att iterera igenom kollektionen och räkna antalet element, medan Length är ett statiskt värde som kan återges direkt.

Semantik

Jo, för vissa typer av datastrukturer så har ju "längd" ingen direkt mening. Men i alla fall List.Count är O(1), List är en vanlig dynamisk array och håller ändå koll på antalet element.

Permalänk
Medlem
Skrivet av perost:

Det fungerar inte eftersom minaInlägg är en List<string[]> medan minaInlägg[i] är en string[], och C# har av någon anledning olika sätt att ta reda på längden beroende på om det är en s.k. "Collection" (som t.ex. List) eller en array.

Längden av en List får man därför med Count istället för Length, d.v.s. minaInlägg.Count för att få längden på listan eller minaInlägg[i].Length för att få längden på en specifik array i listan.

Ja, det är ganska idiotiskt, men det finns säkert någon obskyr teknisk anledning till att de valt att göra så

Då du skapar en array så måste du ange antalet index (Lenght) och detta värde är oföränderligt.
Längd motsvara alltså maximalt antal objekt som kan existera i arrayen.
Dessa platser kan vara tomma/null refernser, men en iteration går ändå över alla dessa index.

var arr = new int[5]; for(var i = 0; i < arr.Length; i++) { Console.WriteLine(i); } // 0 // 1 // 2 // 3 // 4

En List har en egenskap för Count som räknas ut en gång och sedan ökas/tas bort på varje gång man lägger till / tar bort värden.
Count är nuvarande antalet värden i listan, inte hur lång listan är (då den kan ändras dynamiskt och har därför ingen maxlängd).

var list = new List<int>(); for(var i = 0; i < list.Count; i++) { Console.WriteLine(i); } // Skriver inte ut något.

Permalänk

Tusen tack för alla svar. Jag testade count nu och det fungerar bättre. Dock så söker den igenom varje inlägg var för sig. Jag har ju 3 gamla inlägg sparade i bloggen. När jag söker på ordet första så får jag träff, inte träff, inte träff. När jag söker på andra så får jag inte träff, träff, inte träff. Alltså så räknar den även upp alla som jag inte träffar på. Hmm, hur kan jag lösa detta. Det borde ju ha med if loopen att göra?

Permalänk
Medlem
Skrivet av YourHonour:

Tusen tack för alla svar. Jag testade count nu och det fungerar bättre. Dock så söker den igenom varje inlägg var för sig. Jag har ju 3 gamla inlägg sparade i bloggen. När jag söker på ordet första så får jag träff, inte träff, inte träff. När jag söker på andra så får jag inte träff, träff, inte träff. Alltså så räknar den även upp alla som jag inte träffar på. Hmm, hur kan jag lösa detta. Det borde ju ha med if loopen att göra?

Om du vill avbryta loopen efter en träff så använder du

break;

Permalänk
Skrivet av zaibuf:

Om du vill avbryta loopen efter en träff så använder du

break;

Jag tänkte med det, men då kommer det bara ett svar. Om jag söker efter det första inlägget så blir det träff, söker jag efter det andra inlägget så blir det ingen träff. Eftersom den bara går igenom en gång.

Permalänk
Medlem
Skrivet av YourHonour:

Jag tänkte med det, men då kommer det bara ett svar. Om jag söker efter det första inlägget så blir det träff, söker jag efter det andra inlägget så blir det ingen träff. Eftersom den bara går igenom en gång.

Du måste frikoppla själva sökningen från rapporteringen av resultatet. D.v.s. sök först igenom inläggen och håll koll på om du hittar någon träff eller ej (t.ex. med en bool-variabel), och skriv sen ut om något inlägg hittades eller ej när sökningen är klar.

Permalänk
Medlem

Jag hade skapat en lista med sökträffar. Om listan blev tom, skriv ut att det blev 0 träffar. Annars, visa upp träffarna.