Loading...
Loading...
Loading...
Loading...
Loading...
foreach
combinatie controlestructuren
Pas je oefening met CRUD-operaties op Student
aan zodat we ook het gemiddelde per vak kunnen opvragen.
Je werkt nog steeds met een List<Student>
.
Optie 5, 6 en 7 tonen nu het gemiddelde voor communicatie, programmeren of webtechnologie (in die volgorde).
Optie 8 stopt het menu.
Nadat er al drie studenten zijn aangemaakt, met 12, 17 en 19 op communicatie:
List
Gebruik je eerdere code voor PlayingCard
om een spelletje "hoger", "lager" toe te voegen.
Eerst wordt GenerateDeck
gebruikt om een lijst aan te maken en toe te kennen aan een variabele.
Een willekeurig getal wordt gegenereerd tussen 0 en de maximale index van een element in de lijst.
De kaart op deze indexpositie wordt toegekend aan een variabele van type PlayingCard
met naam previousCard
.
Deze kaart wordt ook verwijderd uit de lijst.
Volgende stappen herhalen zich zo lang alle kaarten niet zijn gespeeld:
De waarde van previousCard
wordt getoond.
Een willekeurig getal wordt gegenereerd tussen 0 en de maximale index van een element in de lijst.
De kaart op deze indexpositie wordt toegekend aan een variabele van type PlayingCard
met naam currentCard
.
Deze kaart wordt ook verwijderd uit de lijst.
De gebruiker krijgt de vraag of de waarde van currentCard
hoger, lager of gelijk aan de waarde van previousCard
is.
currentCard
vervang previousCard
Het spel stopt als de gebruiker een fout maakt of als het spel kaarten op is.
Noem de methode om het spel op te starten HigherLower()
Een List<> collectie is de meest standaard collectie die je kan beschouwen als een veiligere variant op een een doodnormale array.
De Generieke List<>
klasse bevindt zich in de System.Collections.Generic
namespace. Je dient deze namespace dus als using
bovenaan toe te voegen wil je deze klasse kunnen gebruiken.
De klasse List<>
is een zogenaamde generieke klasse. Tussen de < >
tekens plaatsen we het type dat de lijst zal moeten gaan bevatten. Bijvoorbeeld:
List<int> alleGetallen= new List<int>();
List<bool> binaryList = new List<bool>();
List<Pokemon> pokeDex = new List<Pokemon>();
List<string[]> listOfStringarrays = new List<string[]>();
Zoals je ziet hoeven we bij het aanmaken van een List
geen begingrootte mee te geven, wat we wel bij arrays moeten doen. Dit is een van de voordelen van List
: ze groeien mee.
Via de Add()
methode kan je elementen toevoegen aan de lijst. Je dient als parameter aan de methode mee te geven wat je aan de lijst wenst toe te voegen. Deze parameter moet uiteraard van het type zijn dat de List
verwacht.
In volgende voorbeeld maken we een List aan die objecten van het type string mag bevatten en vervolgens plaatsen we er twee elementen in.
Het leuke van een List is dat je deze ook kan gebruiken als een gewone array, waarbij je mbv de indexer elementen kan aanroepen. Stel bijvoorbeeld dat we een lijst hebben met minstens 4 strings in. Volgende code toont hoe we de string op positie 3 kunnen uitlezen en hoe we die op positie 2 overschrijven:
Ook de klassieke werking met for
blijft gelden. De enige aanpassing is dat List<>
niet met Length
werkt maar met Count
.
Interessante methoden en properties voorts zijn:
Clear()
:methode die de volledige lijst leegmaakt
Insert()
: methode om element op specifieke plaats in lijst toe te voegen, bijvoorbeeld:
voegt de string toe op de tweede plek en schuift de rest naar achter
Contains()
: geef als parameter een specifiek object mee (van het type dat de List<> bevat) om te weten te komen of dat specifieke object in de List<> terug te vinden is. Indien ja dan zal true worden teruggeven.
IndexOf()
: geeft de index terug van het element item in de rij. Indien deze niet in de lijst aanwezig is dan wordt -1 teruggegeven.
RemoveAt()
: verwijder een element op de index die je als parameter meegeeft.
Je kan met een eenvoudige for
of while-loop over een lijst itereren, maar het gebruik van een foreach-loop is toch handiger.
Dit is dan ook de meestgebruikte operatie om eenvoudig en snel een bepaald stuk code toe te passen op ieder element van de lijst:
Wanneer je geen indexering nodig hebt, maar toch snel over alle elementen in een array wenst te gaan, dan is het foreach statement een zeer nuttig is. Een foreach loop zal ieder element in de array een voor een in een tijdelijke variabele plaatsen (de iteration variable). Volgende code toont de werking waarbij we een array van doubles hebben en alle elementen er in op het scherm willen tonen:
De eerste keer dat we in de loop gaan zal het element killdeathRates[0]
aan kdrate
toegewezen worden voor gebruik in de loop-body, vervolgens wordt killdeathRates[1]
toegewezen, enz.
Het voordeel is dat je dus geen teller/index nodig hebt en dat foreach zelf de lengte van de array zal bepalen.
De foreach iteration variable is read-only: je kan dus geen waarden in de array aanpassen, enkel uitlezen.
De foreach gebruik je enkel als je alle elementen van een array wenst te benaderen. In alle andere gevallen zal je een ander soort loop (for, while, etc.) moeten gebruiken.
C# heeft een var
keyword. Je mag dit keyword gebruiken ter vervanging van het type (bv int) op voorwaarde dat de compiler kan achterhalen wat het type moet zijn.
Opgelet: het var
keyword is gewoon een lazy programmer syntax toevoeging om te voorkomen dat je als programmer niet constant het type moet schrijven
Bij javascript heeft var een totaal andere functie: het zegt eigenlijk "het type dat je in deze variabele kan steken is...variabel", m.a.w. het kan de ene keer een string zijn, dan een int. Bij C# gaat dit niet: eens je een variabele aanmaakt dan zal dat type onveranderbaar zijn.
JavaScript is a dynamically typed language, while c# is (usually) a statically typed language (stackoverflow.com)
Wanneer je de Visual Studio code snippet voor foreach gebruikt foreach [tab][tab]
dan zal deze code ook een var gebruiken voor de iteration variabele. De compiler kan aan de te gebruiken array zien wat het type van een individueel element in de array moet zijn. De foreach van zonet kan dus herschreven worden naar:
We vallen in herhaling: ook arrays van objecten zijn mogelijk, net zoals je arrays van valuetypes al kon maken. Ook hier is de werking grotendeels dezelfde. Maar ook hier moet je er rekening mee houden dat de individuele objecten in je array reference values hebben en dus mogelijk null
zijn.
Een array van objecten gebeurt als volgt:
Maar: er staan nog géén objecten in deze array. Alle elementen in deze array zijn nu nog null
. Je zou kunnen zeggen dat we enkel nog maar de parkeerlijnen hebben aangemaakt.
Willen we nu elementen in deze array plaatsen dan moeten dit ook expliciet doen:
Uiteraard kan dit ook in een loop indien relevant voor de opgave.
Probeer je objecten te benaderen die nog niet bestaan dan zal je uiteraard een NullReferenceException
krijgen.
Je kan ook een variant op de object initializer syntax gebruiken waarbij de objecten reeds van bij de start in de array worden aangemaakt. Als extra'tje zorgt dit er ook voor dat we geen lengte moeten meegeven, de compiler zal deze zelf bepalen. Volgende voorbeeld maakt een nieuwe array aan die bestaat uit 2 nieuwe studenten, alsook 1 bestaande (jos
):
Let op de kommapunt helemaal achteraan. Die wordt als eens vergeten.
Van zodra een object in de array staat kan je deze vanuit de array aanspreken d.m.v. de index :
Ook arrays mag je als parameters en returntype gebruiken in methoden. De werking hiervan is identiek aan die van value-types.
foreach
(h11-prijzen)foreach
combinatie controlestructuren
We willen enkele gegevens (prijzen) inlezen van de gebruiker en slechts sommige van deze prijzen tonen.
Werk onderstaande opdracht uit in een statische methode AskForPrices
.
Maak eerst een array die tot 20 prijzen (type double
) kan bewaren.
Vraag aan de gebruiker om 20 prijzen in te voeren en bewaar elke prijs in de array.
Doorloop vervolgens m.b.v. een foreach
-lus de volledige array.
Toon enkel de elementen op het scherm wiens prijs hoger of gelijk is aan €5.00.
Toon op het einde van het programma het gemiddelde van alle prijzen (dus inclusief de lagere prijzen).
Toon alles afgerond tot twee cijfers na de komma.
foreach
genest
List
We willen een kaartenspel programmeren. Om dat te doen, moeten we zeker een lijst kaarten kunnen aanmaken en ook kaarten te kunnen trekken.
Maak een klasse PlayingCard
.
Een kaart heeft 2 eigenschappen (properties)
een getal van 1 tot en met 13 (boer=11, koningin= 12, heer= 13):
een kleur, de zogenaamde "suite". Deze stel je voor via een enumtype Suites
en kan als waarden Clubs
(klaveren), Hearts
(harten), Spades
(schoppen) of Diamonds
(ruiten) zijn.
Schrijf een statische methode GenerateDeck
die een boek kaarten teruggeeft.
Schrijf om dit te bereiken twee foreach
loops die de 52 kaarten van een standaard pak in een List<PlayingCard>
plaatsen.
Doe dit door één lus in een andere te nesten.
Schrijf ook een statische methode ShowShuffledDeck(List<PlayingCard> cards)
die telkens een willekeurige kaart uit de deck trekt en deze aan de gebruiker toont. De kaart wordt na het tonen dus uit de lijst verwijderd.
Doe dit door in iedere stap een willekeurige, geldige index in de lijst met kaarten te berekenen en die kaart uit de lijst te halen.
We gaan nu de Student
-klasse uit een hoofdstuk 8 gebruiken om een List<Student>
van studenten aan te maken. Daarna zullen we een menu tonen om gegevens over studenten in te voeren (student toevoegen, student aanpassen, gegevens over student tonen, student verwijderen). Op de werkvloer worden deze mogelijkheden "CRUD"-operaties genoemd (create, read, update, delete).
Maak eerst (in de klasse Student
) een statische methode ExecuteStudentMenu()
zonder return type. Deze zal, zolang de gebruiker niet aangeeft dat hij wil stoppen, een menu tonen waarin we gegevens kunnen bekijken of wijzigen.
Het menu toont steeds volgende opties:
gegevens van de studenten tonen
een nieuwe student toevoegen
gegevens van een bepaalde student aanpassen
een student uit het systeem verwijderen
stoppen
Je mag voorlopig veronderstellen dat de gebruiker geldige indexposities en gegevens invoert.
Deze keuze toont, via de methode ShowOverview()
en een foreach
-lus, de gegevens van elke student in de lijst. Elk rapport wordt gevolgd door een lege regel. Het is niet erg als er op het einde één regel te veel is.
Voorbeeldinteractie
Nadat er al twee studenten zijn aangemaakt:
Deze keuze voegt een nieuwe student toe.
Voorbeeldinteractie
Bij nul studenten:
Deze keuze staat toe de naam, leeftijd, klasgroep of een van de drie cijfers van de student aan te passen.
Voorbeeldinteractie
Vlak na het aanmaken van een eerste student:
Voorbeeldinteractie
Nadat er al twee studenten zijn aangemaakt: