C# - Sortera och plocka ut likadana ur array

Permalänk
Medlem

C# - Sortera och plocka ut likadana ur array

Hämta flertal existerande dupliceringar ur en array
Frågan lyder: Hur plockar jag ut flertal existerande likadana resultat ur en array?

Input
Användaren ska ange namn och längd av fem personer, när fem personer blivit inskrivna ska en listbox fyllas med de/den som är längst (inte längden, bara namnet). När detta utförts, är det klart.

Krav
Programmet får enbart använda strängar, array och listor.

Existerande källkod för sortering och utplockning:

Hitta högsta värdet:

public void FindMaxValue(int[] integerArray) { int m = 0; for (int i = 0; i < integerArray.Length; i++) { if (m < integerArray[i]) { m = integerArray[i]; } } indexOfDuplicates.Add(Array.IndexOf(integerArray, m)); }

Skriv ut resultat

public void FillListBox() { FindMaxValue(length); foreach (int i in indexOfDuplicates) { listBox1.Items.Add(name[i]); } }

Variabler

public string[] name = new string[] { "Fredrik", "Martin", "Olle", "Erik", "Oskar" }; public int[] length = new int[] { 192, 203, 187, 203, 103 }; public List<int> indexOfDuplicates = new List<int>();

Resultat borde se ut ungefär såhär:

- Martin - Erik

och alltså exkludera alla de som inte är högst.

När vi hittat det högsta värdet, kollar vi hur många som existerar i listan av lika slag, när vi hittat de indexer av dessa objekt skriver vi ut de genom att använda samma index av de hittade heltalen i array name. Eftersom input sker samtidigt kommer dessa två array att ha samma index, exempelvis:

Fredrik
0
192
0

och så vidare

DEN KOD SOM ANVÄNDS OVANFÖR ÄR INTE ETT KRAV ATT ANVÄNDAS UTAN KAN BYTAS UT ELLER REDIGERAS

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem

Du har ju redan kod att utgå ifrån. Och allt tyder på att det här är en skoluppgift så då borde du i alla fall försöka själv! Om du har en mer specifik fråga hjälper jag dig gärna men lite får du allt försöka själv.

Visa signatur

EPoX 8RDA+, XP2500+, 2x256Mb PC3200 (DualCh), Club3D 9800PRO, Seagate 7200.7 160Gb 8Mb Limited edition

Permalänk
Medlem

var maxLängd = hitta maxvärde av längd var längstaPersonerIndex = tom lista som kommer hålla index till de längsta personerna for-iterera över alla längder { om längd[i] == maxLängd { lägg till 'i' i längstaPersonerIndex-listan } } foreach-iterera över längstaPersonerIndex { lägg till namn[index] i listbox }

edit: Nordis har rätt.. du har redan all kod du behöver. Det jag skrev var i princip samma som står i koden du gav.

Visa signatur

Kom-pa-TI-bilitet

Permalänk

Ledsen, missförstånd.

Permalänk
Medlem
Skrivet av Nordis:

Du har ju redan kod att utgå ifrån. Och allt tyder på att det här är en skoluppgift så då borde du i alla fall försöka själv! Om du har en mer specifik fråga hjälper jag dig gärna men lite får du allt försöka själv.

Eftersom jag kommit sådär långt så antar jag att det visar att jag åtminstone försökt och att jag är på gränsen till att jag ska lyckas. Det enda är att jag inte ser mitt misstag om till och med missat att fixa en loop för att gå igenom ALLA resultat, men den stannar på första. Vet inte om jag kan göra en mer exakt svar på vad min fråga är men detta är närmaste jag kan komma tror jag: Hämta ALLA och inte bara en av de likadana värdena i en array och sedan få dess index som referens till den array som innehåller namn, eftersom de anges samtidigt kommer de kunna återge vem som hade längst längd.

Skrivet av Teknocide:

var maxLängd = hitta maxvärde av längd var längstaPersonerIndex = tom lista som kommer hålla index till de längsta personerna for-iterera över alla längder { om längd[i] == maxLängd { lägg till 'i' i längstaPersonerIndex-listan } } foreach-iterera över längstaPersonerIndex { lägg till namn[index] i listbox }

edit: Nordis har rätt.. du har redan all kod du behöver. Det jag skrev var i princip samma som står i koden du gav.

Precis, din kod är motsvarande min redan existerande kod. Det saknas en loop av slag som ska gå igenom alla istället för bara pausa vid första resultatet..

Skrivet av Kaspersky 0_o:

Ledsen, missförstånd.

Vilket missförstånd?

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

Precis, din kod är motsvarande min redan existerande kod. Det saknas en loop av slag som ska gå igenom alla istället för bara pausa vid första resultatet..

Jag trodde det var grundläggande kod du fått av din handledare. Min lösning ska hursomhelst fungera.

Edit: det är fel i din FindMaxValue-metod naturligtvis. Du lägger bara till ett värde.. och på ett väldigt underligt sätt dessutom
Metoden borde även returnera en array istället för att sätta en redan existerande då detta räknas som en odokumenterad sideffekt.

Skickades från m.sweclockers.com

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Jag trodde det var grundläggande kod du fått av din handledare. Min lösning ska hursomhelst fungera.

Edit: det är fel i din FindMaxValue-metod naturligtvis. Du lägger bara till ett värde.. och på ett väldigt underligt sätt dessutom
Metoden borde även returnera en array istället för att sätta en redan existerande då detta räknas som en odokumenterad sideffekt.

Skickades från m.sweclockers.com

Oh, jo det är sant förstås. Nej förklaringen om vad jag ska göra är av handledaren. Den kod som ni ser är byggd från scratch (tom WFA). Jag ber om hjälp när jag velat bort mig i skallen, inte när jag får uppgiften vart enligt din förklaring ska det appliceras? Som en egen metod eller i min nuvarande FindMaxValue?

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

Oh, jo det är sant förstås. Nej förklaringen om vad jag ska göra är av handledaren. Den kod som ni ser är byggd från scratch (tom WFA). Jag ber om hjälp när jag velat bort mig i skallen, inte när jag får uppgiften vart enligt din förklaring ska det appliceras? Som en egen metod eller i min nuvarande FindMaxValue?

IEnumerable<> har en metod för att hitta ett maxvärde i en enumerable som du kan använda. Själva "hitta maxvärdet"-delen av din metod ser annars helt rätt ut.

val maxValue = integerArray.Max();

Istället kan du skapa en metod

IEnumerable<int> AllIndexOf<T> (T match, IEnumerable<T> values) { ... }

eller om du inte är så van vid generics,

int[] AllIndexOf(int match, int[] values) { ... }

Vi har dessutom redan nosat på extension-metoder, vilka är väldigt roliga men kan vara lite svåra att få skallen runt. I vilket fall skulle det se ut någonting åt detta hållet

public static class IEnumerableExtensions { public static IEnumerable<int> AllIndexOf(this IEnumerable<T>, T match) { ... } }

Det sistnämnda kan då användas så här:

var max = minIntArray.Max(); var allaIndexSomMatcharMax = minIntArray.AllIndexOf(max); loopa över allaIndexSomMatcharMax och lägg till motsvarande minNamnArray[index] i listboxen

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

IEnumerable<> har en metod för att hitta ett maxvärde i en enumerable som du kan använda. Själva "hitta maxvärdet"-delen av din metod ser annars helt rätt ut.

val maxValue = integerArray.Max();

Istället kan du skapa en metod

IEnumerable<int> AllIndexOf<T> (T match, IEnumerable<T> values) { ... }

eller om du inte är så van vid generics,

int[] AllIndexOf(int match, int[] values) { ... }

Vi har dessutom redan nosat på extension-metoder, vilka är väldigt roliga men kan vara lite svåra att få skallen runt. I vilket fall skulle det se ut någonting åt detta hållet

public static class IEnumerableExtensions { public static IEnumerable<int> AllIndexOf(this IEnumerable<T>, T match) { ... } }

Det sistnämnda kan då användas så här:

var max = minIntArray.Max(); var allaIndexSomMatcharMax = minIntArray.AllIndexOf(max); loopa över allaIndexSomMatcharMax och lägg till motsvarande minNamnArray[index] i listboxen

namespace IEnumberableExtension { public static class ExtensionMethods { public static IEnumerable<int> AllIndexOf(this IEnumerable<T>, T match) { } } }

public static void GetHighestOfArray(int[] integerArray) { var max = integerArray.Max(); var allaIndexSomMatcharMax = IEnumberableExtension.ExtensionMethods.AllIndexOf(max); }

Får bara felen att det saknas en namespace för T och jag vet inte riktigt vad jag ska returnera i AllIndexOf...

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

namespace IEnumberableExtension { public static class ExtensionMethods { public static IEnumerable<int> AllIndexOf(this IEnumerable<T>, T match) { } } }

public static void GetHighestOfArray(int[] integerArray) { var max = integerArray.Max(); var allaIndexSomMatcharMax = IEnumberableExtension.ExtensionMethods.AllIndexOf(max); }

Får bara felen att det saknas en namespace för T och jag vet inte riktigt vad jag ska returnera i AllIndexOf...

Sorry, det ska vara public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T>, T match)

Metoden ska returnera en lista (eller array) som innehåller de element i this IEnumerable<T> som är lika med match. Exempelvis

var list = new List<int> { 2, 5, 6, 8, 5, 1 }; list.AllIndexOf(5); // ger 1 och 4

Skickades från m.sweclockers.com

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Sorry, det ska vara public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T>, T match)

Metoden ska returnera en lista (eller array) som innehåller de element i this IEnumerable<T> som är lika med match. Exempelvis

var list = new List<int> { 2, 5, 6, 8, 5, 1 }; list.AllIndexOf(5); // ger 1 och 4

Skickades från m.sweclockers.com

Okej men hur ser själva "return" ut, vad ska anges?
Får dessutom ytterligare fel, nu är det inte ett namespace som saknas utan felet ligger i kommat:
public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T>, T match)

Felet anges som: identifier expected; och det förväntade att en return saknas för:

public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T>, T match) { }

Uppskattar verkligen hjälpen

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

Okej men hur ser själva "return" ut, vad ska anges?
Får dessutom ytterligare fel, nu är det inte ett namespace som saknas utan felet ligger i kommat:
public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T>, T match)

Felet anges som: identifier expected; och det förväntade att en return saknas för:

public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T>, T match) { }

Uppskattar verkligen hjälpen

Ja ursäkta mig igen, det ska naturligtvis vara

public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T> values, T match) { var result = new List<int>(); // kod som lägger alla värden i values som matchar match i result return result; }

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Ja ursäkta mig igen, det ska naturligtvis vara

public static IEnumerable<int> AllIndexOf<T>(this IEnumerable<T> values, T match) { var result = new List<int>(); // kod som lägger alla värden i values som matchar match i result return result; }

Lyckades få det att funka men har istället fått problem med användarinput för att fylla de array jag har, string[] name och int[] length.

Förstår fortfarande inte riktigt hur man loopar igenom en lista för att fylla den ett x antal gånger, tanken är att jag ska
låta en användare skriva in 5 personers namn och längd och sedan som ovan löst presentera dem. Men med predefinierade
namn och längder har programmet funkat, nu i beta så tog jag bort dom (lämnat tomma listor) för att titta om de funka.. har däremot ingen aning om hur man lägger till i en array, bara vanliga listor som List<string> eller List<int>

Min nuvarande kod:

private void button1_Click(object sender, EventArgs e) { AddToList(textBox1.Text, Convert.ToInt32(textBox2.Text)); if (name.Length == 5) { GetHighestOfArray(length); } } public void AddToList(string input, int Input) { for (int i = 0; i < name.Length; i++) { name[i] = input; length[i] = Input; } }

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem

Jag tycker du förlorar på att ha en egen metod för GetHighestOfArray när det redan finns definierad som one-liner i standard API:t. AddToList tror jag är ett sidospår.

Med AllIndexOf-metoden så går filtreringsuppgiften att lösa på tre rader.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Jag tycker du förlorar på att ha en egen metod för GetHighestOfArray när det redan finns definierad som one-liner i standard API:t. AddToList tror jag är ett sidospår.

Med AllIndexOf-metoden så går filtreringsuppgiften att lösa på tre rader.

Men jag kan inte filtrera innehållet i en array om array'en är tom, jag måste ju definiera innehållet.
GetHighestOfArray?

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

Men jag kan inte filtrera innehållet i en array om array'en är tom, jag måste ju definiera innehållet.
GetHighestOfArray?

Om jag förstått dig rätt har du fem namnfält och fem längdfält. Första steget är att flytta inmatningarna från dessa fält till någon sorts collection-typ, listor eller arrays fungerar bra. Jag skulle personligen ha valt att använda arrays eftersom vi vet precis hur många värden ditt program kommer ta in. Efter att vi har namn och längd på plats väljer vi det största värdet ur längd-arrayen, hittar alla index av detta värde i samma array, och plockar ut motsvarande index ur namnarrayen.

Pseudo:

var namn = ny sträng-array med fem positioner var längd = ny int-array med fem positioner // fyll arrayerna med värde från fält namn[0 till 4] = namnfält1, ... namnfält5 längd[0 till 4] = längdfält1, ... längdfält5 var max = största värdet av längd // ledtråd, använd längd.Max() var indexes = längd.AllIndexOf(max) för varje item i indexes: lägg till namn[item] plus ny rad i utfältet

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Om jag förstått dig rätt har du fem namnfält och fem längdfält. Första steget är att flytta inmatningarna från dessa fält till någon sorts collection-typ, listor eller arrays fungerar bra. Jag skulle personligen ha valt att använda arrays eftersom vi vet precis hur många värden ditt program kommer ta in. Efter att vi har namn och längd på plats väljer vi det största värdet ur längd-arrayen, hittar alla index av detta värde i samma array, och plockar ut motsvarande index ur namnarrayen.

Pseudo:

var namn = ny sträng-array med fem positioner var längd = ny int-array med fem positioner // fyll arrayerna med värde från fält namn[0 till 4] = namnfält1, ... namnfält5 längd[0 till 4] = längdfält1, ... längdfält5 var max = största värdet av längd // ledtråd, använd längd.Max() var indexes = längd.AllIndexOf(max) för varje item i indexes: lägg till namn[item] plus ny rad i utfältet

Ja precis, men problemet är inte själva koden i sig eftersom den funkar med predefinierade alternativ i listan, grejen är den att det ska inte vara så. Användaren ska definiera vad listan innehåller och programmet printar sen ut resultaten. I nuläge kan man inte lägga in i listan för jag har ingen som helst aning hur det funkar i en vanlig array >_< antog att det skulle vara name[0,1,2,3,4,5 osv] = textBox1.Text; //eller annan variabel. Men det verkar inte funka...
Så när jag väl kör AllIndexOf så finns det ju ingenting att köra det på eftersom mina arrays antingen blir tomma eller fyllda med och samma på grund av min kassa for loop :C

Som du säger i din code snippet:

för varje item i indexes: lägg till namn[item] plus ny rad i utfältet

Detta har jag redan testat.

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

Ja precis, men problemet är inte själva koden i sig eftersom den funkar med predefinierade alternativ i listan, grejen är den att det ska inte vara så. Användaren ska definiera vad listan innehåller och programmet printar sen ut resultaten. I nuläge kan man inte lägga in i listan för jag har ingen som helst aning hur det funkar i en vanlig array >_< antog att det skulle vara name[0,1,2,3,4,5 osv] = textBox1.Text; //eller annan variabel. Men det verkar inte funka...
Så när jag väl kör AllIndexOf så finns det ju ingenting att köra det på eftersom mina arrays antingen blir tomma eller fyllda med och samma på grund av min kassa for loop :C

Som du säger i din code snippet:

för varje item i indexes: lägg till namn[item] plus ny rad i utfältet

Detta har jag redan testat.

var enArrayAvTypStringMedLängdFem = new string[5]; enArrayAvTypStringMedLängdFem[0] = textbox1.Text; enArrayAvTypStringMedLängdFem[1] = textbox2.Text; enArrayAvTypStringMedLängdFem[2] = textbox3.Text; enArrayAvTypStringMedLängdFem[3] = textbox4.Text; enArrayAvTypStringMedLängdFem[4] = textbox5.Text;

Är detta vad du menar..?

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

var enArrayAvTypStringMedLängdFem = new string[5]; enArrayAvTypStringMedLängdFem[0] = textbox1.Text; enArrayAvTypStringMedLängdFem[1] = textbox2.Text; enArrayAvTypStringMedLängdFem[2] = textbox3.Text; enArrayAvTypStringMedLängdFem[3] = textbox4.Text; enArrayAvTypStringMedLängdFem[4] = textbox5.Text;

Är detta vad du menar..?

Precis men det verkar inte funka eftersom i en for loop så funkar det inte.
Angav: textBox1.Text var "Alfons" med längd 193, jag fick ca 5 st Alfons i min lista.
Ska försöka igen.

Edit: Felet ligger i loopen, den lägger till antalet i istället för i index i

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

Precis men det verkar inte funka eftersom i en for loop så funkar det inte.
Angav: textBox1.Text var "Alfons" med längd 193, jag fick ca 5 st Alfons i min lista.
Ska försöka igen.

Om textBox1 innehåller texten "Alfons" och du skriver något i stil med

for (int i=0; i < 5; i++) { names[i] = textBox1.Text; }

... så får du naturligtvis Alfons i hela arrayen.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Om textBox1 innehåller texten "Alfons" och du skriver något i stil med

for (int i=0; i < 5; i++) { names[i] = textBox1.Text; }

... så får du naturligtvis Alfons i hela arrayen.

Sant, nu när du sa det förstod jag vad som var felet. Fixat nu
Funkar. Tack för hjälpen.

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
AzireVPN - Felkod40