Toon posts:

[C#] lijsten in een lijst zijn niet uniek; IDictionary

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Geliefde tweakertjes,

Ik zit met een probleem dat te maken heeft met het Generics gedeelte van C#. De situatie is als volgt:

Ik heb een xml file genaamd "vakken.xml". Deze xml file bevat informatie over een bepaald vak dat op een opleiding gegeven wordt. De informatie over een vak wordt opgeslagen op deze manier, in volgorde onder elkaar:

- een regel met de afkorting van het vak.
- een regel met de naam van het vak.
- een of meer regels met de groepen die dit vak volgen.
- een of meer regels met de afkortingen van de docenten die deze les geven.
- een regel met de soort les.
- een of meer regels met informatie over de datum, begintijd, eindtijd, locatie van het gegeven vak.

Nu is het zo dat een bepaald vak in de xml file beschreven kan worden (waar het soort vak bijv. "th", oftewel theorie is), en dit vak even later in de xml file nog een keer terug kan komen, maar dan met andere data/uren, omdat het dan bijv. om de vaksoort "pr", oftewel prakticum, gaat.

Mijn eerste oplossing bestond uit het vullen van een lijst (bijv. een ArrayList) met alle informatie van een vak, en dit weg te laten schrijven naar een bepaalde file (de file krijgt de naam van het vak) door die file te laten appenden, in de zin van: lijst vullen met vakinformatie, file appenden met deze vakinformatie, lijst leegmaken, en maar door gaan tot het einde van de file.
Ik ben er inmiddels achtergekomen dat dit niet erg efficïent is, omdat een bepaald vak pas naar een file geschreven wordt, als het vorige vak helemaal weggeschreven is. Deze seriële manier van werken (inclusief het vaak openen en sluiten van streamwriters ed) is natuurlijk niet erg efficiënt..

Vervolgens had ik het idee om een vakkenlijst met vakinformatielijsten aan te leggen. Iedere lijst zou een unieke naam hebben, en vervolgens alle vakinformatie bevatten. Hiervoor leek een implimentatie van IDictionary mij zeer geschikt:

IDictionary <string, IList<string>> subjectsList = new Dictionary <string, IList<string>>();

Een kort voorbeeldje: tijdens het lezen van de vakken.xml file komt de leest de streamReader een bepaalde regel uit, die de naam van een vak bevat. Er zou op dat moment een nieuwe lijst gemaakt moeten worden in de algemene lijst subjectsList:

// De algemene lijst bevat nog geen lijst met vakinformatie.
if (!(subjectsList.containsKey(naam van het vak)))
{
// Maak een nieuwe lijst met de naam van het vak die informatie over het vak moet gaan bevatten.
IList<string> subjectInformationList = new List<string>();
}
// De algemene lijst bevat wél een lijst met vakinformatie.
else
{
// Pak de lijst met vakinformatie uit de algemene subjectsList, gooi deze in een tijdelijke list.
}

Ik heb nu, als het goed is, een subjectInformationList. Deze ga ik vullen met alle informatie (bijv. de afkortingen van de docenten, lestijden, etc. etc.).

Op het moment dat de streamReader aangekomen is bij een regel in de xml file die informatie geeft over een vak, weten we dat alle informatie van het vorige vak in de subjectInformationList staat. De subjectInformationList mag dus worden toegevoegd aan de subjectsList.

Daarna mag de subjectInformationList geleegd worden, zodat hij opnieuw gevuld kan worden met informatie over een (ander) vak. Hier herhaalt zich het hele circus dat ik zojuist beschreven heb.

Hier zit echter een probleem. De subjectInformationList wordt keurig gevuld met informatie en deze lijst wordt keurig toegevoegd aan de subjectsList. Zodra de streamReader klaar is met het lezen van de xml file, en het maken en toevoegen van subjectInformationLists aan de subjectsList, blijkt echter dat de subjectsList wél gevuld is met lijsten met vaknamen, maar dat de count van het aantal elementen van iedere subjectInformationList op nul staat.

Ik heb hier eens flink over nagedacht, en kwam tot de conclusie dat het komt omdat ik, vlak na het toevoegen van een subjectInformationList aan de subjectsList, het commando subjectInformationList.Clear() aan roep (zodat de lijst opnieuw gevuld kan worden met een nieuw vak).
Omdat de subjectList echter gevuld wordt met dezelfde een veelvoud van de subjectInformationList, maakt hij dus alle vormen hiervan leeg. Uiteraard is dit ongewenst.

Een idee om dit op te lossen, zou iets zijn als het creëren van een unieke list. Niet alleen de key van de list moet uniek zijn, maar ook de naam van de list zelf. Echter: hoe krijg ik zoiets voor elkaar? Of weet iemand een andere oplossing?

Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ik ben erg trots dat ik je textueel uitgebreide OP helemaal heb gelezen, mijn oog viel op het volgende stuk code:
Verwijderd schreef op vrijdag 14 november 2008 @ 13:41:
<snip>
// De algemene lijst bevat nog geen lijst met vakinformatie.
if (!(subjectsList.containsKey(naam van het vak)))
{
// Maak een nieuwe lijst met de naam van het vak die informatie over het vak moet gaan bevatten.
IList<string> subjectInformationList = new List<string>();
}
// De algemene lijst bevat wél een lijst met vakinformatie.
else
{
// Pak de lijst met vakinformatie uit de algemene subjectsList, gooi deze in een tijdelijke list.
}
...
in combinatie met deze alinea:
Ik heb hier eens flink over nagedacht, en kwam tot de conclusie dat het komt omdat ik, vlak na het toevoegen van een subjectInformationList aan de subjectsList, het commando subjectInformationList.Clear() aan roep (zodat de lijst opnieuw gevuld kan worden met een nieuw vak).
<snip>
Je weet toch wel wat new doet? Want volgens mij hoef je de lijst dus niet te clearen als je steeds een nieuwe instantie aanmaakt.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verdorie..zou het zo simpel kunnen zin? Nu voel ik me helemaal een amateur:(

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb het geprobeerd zonder Clear() aan te roepen; het heeft tot gevolg dat ALLE subjectInformationList geappend worden met nieuwe vakinformatie; ook de lijsten die al zijn weggeschreven naar de subjectList.

Acties:
  • 0 Henk 'm!

  • DutchCommando
  • Registratie: November 2000
  • Laatst online: 22:39
Verwijderd schreef op vrijdag 14 november 2008 @ 13:41:
Ik heb hier eens flink over nagedacht, en kwam tot de conclusie dat het komt omdat ik, vlak na het toevoegen van een subjectInformationList aan de subjectsList, het commando subjectInformationList.Clear() aan roep (zodat de lijst opnieuw gevuld kan worden met een nieuw vak).
Omdat de subjectList echter gevuld wordt met dezelfde een veelvoud van de subjectInformationList, maakt hij dus alle vormen hiervan leeg. Uiteraard is dit ongewenst.
Je maakt een nieuwe List (subjectInformationList) aan met new. Vervolgens vul je deze lijst met informatie en voeg je een verwijzing naar deze List toe aan een Dictionary. Let wel, je voegt een verwijzing toe, niet een kopie! Vervolgens roep je de Clear methode van de subjectInformationList aan wat betekent dat alle items uit deze List verwijderd worden. Aangezien de Dictionary niets meer dan een verwijzing naar de List bevat heeft hij ook geen toegang meer tot elementen die in de lijst stonden.

Lees voor bovenstaande je in op het verschil tussen value en reference types.

Acties:
  • 0 Henk 'm!

  • CMG
  • Registratie: Februari 2002
  • Laatst online: 10-12-2024

CMG

Ik kan het niet helemaal volgen, maar het lijkt alsof je op het verkeerde niveau een .clear uitvoerd (dit wist alle items). Als je wat code kan posten kan ik er even naar kijken.

Verder nog twee kleine opmerkingen:
IDictionary <string, IList<string>> subjectsList = new Dictionary <string, IList<string>>();
Waarom declare je alles als de interface en niet de implentatie?
Ik zou het zo doen: Dictionarty<String,List<String>> subjectList = new Dictionarty<String,List<String>>();
if (!(subjectsList.containsKey(naam van het vak)))
het ronde haakje na '!' is niet nodig, maakt het misschien wat leesbaarder (minder haakjes is altijd fijner).

NKCSS - Projects - YouTube

Pagina: 1