[C#] waardes in een hashtable veranderen

Pagina: 1
Acties:

Onderwerpen


Verwijderd

Topicstarter
Hallo,

Ik ben bezig met een functie op wat gegevens uit een bestand in een HashTable op te slaan. De opbouw van de Hashtable is als volgt:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HashTable AllValues = new HashTable();

// Aanmaken van de eerste entry
string key = "key_01";
HashTable value = new HashTable();
value.Add("subkey1", "lalala");
value.Add("subkey2", "hihih");
value.Add("subkey3", "hahaha");
AllValues.Add(key, value);

// En nu de tweede (gebeurt in een lus, dus waardes worden NIET hergebruikt)
string key = "key_02";
HashTable value = new HashTable();
value.Add("subkey1", "mooo");
value.Add("subkey2", "woof");
AllValues.Add(key, value);


De uitkomst zou dus als volgt moeten zijn:
C#:
1
2
3
4
5
6
7
8
HashTable value1 = AllValues["key_01"] as HashTable;
string subvalue1 = value1["subkey1"].ToString(); // "lalala"
string subvalue2 = value1["subkey2"].ToString(); // "hihihi"
string subvalue3 = value1["subkey3"].ToString(); // "hahaha"

HashTable value2 = AllValues["key_02"] as HashTable;
string subvalue1 = value2["subkey1"].ToString(); // "mooo"
string subvalue2 = value2["subkey2"].ToString(); // "woof"


Dit zou het moeten zijn, echter als ik "key_01" in de HashTable heb staan, en later doormiddel van "HashTable.Add()" een nieuwe entry toevoeg, worden de values van ALLE entries overschreven. Dus "value1" heeft zijn eigen key, maar de values zijn die van "value2".

Na de eerste entry is de opbouw als volgt:
C#:
1
2
3
4
HashTable value1 = AllValues["key_01"] as HashTable;
string subvalue1 = value1["subkey1"].ToString(); // "lalala"
string subvalue2 = value1["subkey2"].ToString(); // "hihihi"
string subvalue3 = value1["subkey3"].ToString(); // "hahaha"


Na de 2e entry is de opbouw als volgt:
C#:
1
2
3
4
5
6
7
8
HashTable value1 = AllValues["key_01"] as HashTable;
string subvalue1 = value1["subkey1"].ToString(); // "mooo"
string subvalue2 = value1["subkey2"].ToString(); // "woof"
// string subvalue3 = value1["subkey3"].ToString(); // ERROR, BESTAAT NIET!

HashTable value2 = AllValues["key_02"] as HashTable;
string subvalue1 = value2["subkey1"].ToString(); // "mooo"
string subvalue2 = value2["subkey2"].ToString(); // "woof"


Ik snap niet hoe het mogelijk is, aangezien ik nergens de gegevens ophaal of wijzig (met debugged stop ik als het bestand is uitgelezen). Heeft iemand enig idee wat er misgaat?

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Toon eens de exacte code zoals je die gebruikt ...

Als ik nl. deze code heb:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
static void Main( string[] args )
{
    Dictionary<string, Dictionary<string,string>> allValues 
                = new Dictionary<string, Dictionary<string, string>> ();

    for( int i = 0; i < 3; i++ )
    {
        string key = "key" + i.ToString ();

        Dictionary<string,string> values = new Dictionary<string, string> ();

        for( int j = 0; j < 5; j++ )
        {
            string subkey = String.Format ("subkey{0}_{1}", i, j);

            values.Add (subkey, "subvalue" + j);

        }

        allValues.Add (key, values);
    }

    foreach( KeyValuePair<string, Dictionary<string,string>> kvp in allValues )
    {
        Console.WriteLine (String.Format ("Contents of {0}", kvp.Key));

        foreach( KeyValuePair<string,string> subvalues in kvp.Value )
        {
             Console.WriteLine (String.Format(" key: {0} - value: {1}", subvalues.Key, subvalues.Value));
        }

    }

    Console.ReadLine ();
}


Dan krijg ik nl. volgende output:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Contents of key0
 key: subkey0_0 - value: subvalue0
 key: subkey0_1 - value: subvalue1
 key: subkey0_2 - value: subvalue2
 key: subkey0_3 - value: subvalue3
 key: subkey0_4 - value: subvalue4
Contents of key1
 key: subkey1_0 - value: subvalue0
 key: subkey1_1 - value: subvalue1
 key: subkey1_2 - value: subvalue2
 key: subkey1_3 - value: subvalue3
 key: subkey1_4 - value: subvalue4
Contents of key2
 key: subkey2_0 - value: subvalue0
 key: subkey2_1 - value: subvalue1
 key: subkey2_2 - value: subvalue2
 key: subkey2_3 - value: subvalue3
 key: subkey2_4 - value: subvalue4


Declareer jij je variablen uit je loop misschien ?

[ Voor 94% gewijzigd door whoami op 10-09-2008 20:34 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
Aangezien het verspreid is zal ik het zo goed mogelijk proberen samen te vatten :P

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Globale waarden
Hashtable Queries_RCP = new Hashtable();

// Functie om bestand te lezen
string line = "";
string current_name = "";
Hashtable current_values = new Hashtable();
while (line != "#EOF")
{
    line = file_select.ReadLine();
    if (line != "" & line != "#EOF")
    {
        if (line == "#")
        {
            Queries_RCP.Add(current_name, current_values);
            current_name = "";
            current_values.Clear();
        }
        else if (line.Substring(0, 1) == "\t")
        {
            string[] s = line.Substring(1).Split('=');
            current_values.Add(s[0].ToString(), s[1].ToString());
        }
        else
        {
            current_name = line;
        }
    }
}


Inhoud van het bestand:
code:
1
2
3
4
5
6
7
8
9
10
MYSQL_PRIMARYSHOPS
    table=shops_mysql
    what=shops_id,server_external,username,password,database,type
    order=shops_id|ASC
#
MAIN_SHOPS
    table=shops
    what=shops_id,name
#
#EOF


Ik merk nu dat ik het fout in mijn 1e post heb vermeldt, de waardes worden wel hergebruikt, echter nadat de waardes in de "Queries_RCP"-hashtable zijn toegevoegd, worden ze geleegd.

  • kiekerjan
  • Registratie: September 2000
  • Laatst online: 20:45
Het probleem is dat je steeds hetzelfde hashtable object opslaat in de Queries_RCP hashtable. Omdat je de hashtable steeds leegmaakt (clear()) heb je aan het eind 1 hashtable onder verschillende keys met alleen de inhoud van de laatst toegevoegde waarden. De oplossing: voor elke sub hashtable die je wilt toevoegen een nieuwe instantie maken.
Probeer het volgende eens: (alleen regel 17 aangepast)


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Globale waarden
Hashtable Queries_RCP = new Hashtable();

// Functie om bestand te lezen
string line = "";
string current_name = "";
Hashtable current_values = new Hashtable();
while (line != "#EOF")
{
    line = file_select.ReadLine();
    if (line != "" & line != "#EOF")
    {
        if (line == "#")
        {
            Queries_RCP.Add(current_name, current_values);
            current_name = "";
            current_values = new Hashtable();
        }
        else if (line.Substring(0, 1) == "\t")
        {
            string[] s = line.Substring(1).Split('=');
            current_values.Add(s[0].ToString(), s[1].ToString());
        }
        else
        {
            current_name = line;
        }
    }
}

[ Voor 7% gewijzigd door kiekerjan op 10-09-2008 20:55 ]

These are my principles. If you don't like them I have others.


Verwijderd

Topicstarter
Wow ... Zo eenvoudig :o Ik vind het wel vreemd, je zou zeggen dat Clear(); hetzelfde is als een nieuwe hashtable aanmaken.

Bedankt beide :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Tja, je hashtable initialiseer je één keer. Je hashtable is een reference type.

Je stopt wat waardes in je hashtable.
Je voegt die hashtable toe aan je Queries_RCP hashtable.

De variable 'values' bevat een referentie naar een stuk geheugen op de heap.
De entry in Queries_RCP die je toegevoegd hebt (die 'values' hashtable dus) verwijst naar hetzelfde stuk geheugen op de heap.
Jij doet values.Clear, dat wil dus zeggen dat de items uit die hashtable gecleared worden, maar je entry in Queries_RCP verwijst gewoon naar dezelfde hashtable... You do the math.

Kijk:
code:
1
2
3
4
5
6
7
8
9
Hashtable melp = new Hashtable();
melp.Add ("bliep" , "blop");

Hashtable another = melp;

melp.Clear();

Console.WriteLine (melp.Count);
Console.WriteLine (copy.Count);


Basic reference types / value types kennis. :)

Wat jij dus moet doen, is in je while loop ervoor zorgen dat je een nieuwe instantie creeërt van current_values.

/spuit 11 als je nog even snel wat tussendoor wilt doen ...

[ Voor 3% gewijzigd door whoami op 10-09-2008 20:59 ]

https://fgheysels.github.io/


Verwijderd

Een hashtable is in principe een lijst van key-value pairs, niet een key, subkey, value combi.
Wil je die functionaliteit, dan zul je een eigen collection moeten maken.

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Verwijderd schreef op woensdag 10 september 2008 @ 21:01:
Een hashtable is in principe een lijst van key-value pairs, niet een key, subkey, value combi.
Wil je die functionaliteit, dan zul je een eigen collection moeten maken.
Wat is er mis met een Dictionary<string, Dictionary<string, string>> die je precies dezelfde functionaliteit geeft ?

[ Voor 55% gewijzigd door whoami op 10-09-2008 21:37 ]

https://fgheysels.github.io/


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Behalve dan dat dat z'n probleem niet oplost, het is alleen wat meer typesafe.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Ik wou het niet over die type-safety hebben.
Als je een hashtable/dictionary hebt, die KeyValuePairs bevat van het type (key=string, value=hashtable/dictionary), dan heb je toch ook een soort van 'key-subkey-value' collectie ...

https://fgheysels.github.io/


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Oh het was een reactie op Afterlife, en niet op de TS? In dat geval: Ja, Afterlife, wat is er mis met een Dictionary<string, Dictionary<string, string>>? :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • gorgi_19
  • Registratie: Mei 2002
  • Nu online

gorgi_19

Kruimeltjes zijn weer op :9

Ook in een hashtable kan je hashtables stoppen (met een beetje casten), dus het verschil blijft alleen op typesafety?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
.oisyn schreef op woensdag 10 september 2008 @ 21:30:
Oh het was een reactie op Afterlife, en niet op de TS? In dat geval: Ja, Afterlife, wat is er mis met een Dictionary<string, Dictionary<string, string>>? :P
De TS zijn probleem is al min of meer opgelost. :P

https://fgheysels.github.io/


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Verwijderd schreef op woensdag 10 september 2008 @ 20:56:
Ik vind het wel vreemd, je zou zeggen dat Clear(); hetzelfde is als een nieuwe hashtable aanmaken.
Jij veegtt ook nooit een whiteboard uit als iemand je vraagt "Wil je het whiteboard uitvegen", maar interpreteert dat als "bestel een nieuwe"?

[ Voor 13% gewijzigd door Confusion op 10-09-2008 21:54 ]

Wie trösten wir uns, die Mörder aller Mörder?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wellicht gebruiken ze watervaste stiften? :+

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • pedorus
  • Registratie: Januari 2008
  • Niet online
.oisyn schreef op woensdag 10 september 2008 @ 22:31:
Wellicht gebruiken ze watervaste stiften? :+
Verwijderd schreef op woensdag 10 september 2008 @ 20:43:
Inhoud van het bestand:
code:
1
2
3
4
5
6
7
8
9
10
MYSQL_PRIMARYSHOPS
    table=shops_mysql
    what=shops_id,server_external,username,password,database,type
    order=shops_id|ASC
#
MAIN_SHOPS
    table=shops
    what=shops_id,name
#
#EOF
Hm, interessant bestandsformaat. Die #EOF op het einde is gek, dat doet denken aan de tijd van de cassettebandjes... :) Zonder dat er #EOF staat krijg je nu gelukkig een nullpointerexception bij Substring, anders was dat een oneindige loop geworden.

Kijk eens naar dingen als:
  • ini-bestanden
  • sql/views
  • creating objects
  • hoe moeilijk het parsen van een ini-bestand is
    C#:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    Dictionary<string, Dictionary<string, string>> sections = 
        new Dictionary<string, Dictionary<string, string>>();
    Dictionary<string, string> keys = new Dictionary<string, string>();
    foreach(string line in File.ReadAllLines("config.ini")) {
        int isPosition;
        if ((line[0] == '[') && (line[line.Length - 1] == ']'))
            sections.Add(line.Substring(1, line.Length - 2), 
                keys = new Dictionary<string, string>());
        else if ((line[0] != ';') && ((isPosition = line.IndexOf('=')) >= 0))
            keys.Add(line.Substring(0, isPosition), 
                line.Substring(isPosition + 1));
    }

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • gorgi_19
  • Registratie: Mei 2002
  • Nu online

gorgi_19

Kruimeltjes zijn weer op :9

Waarom een ini bestand en geen .config bestand? Met de ConfigurationManager kan je die ook eenvoudig uitlezen?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • pedorus
  • Registratie: Januari 2008
  • Niet online
gorgi_19 schreef op donderdag 11 september 2008 @ 08:26:
Waarom een ini bestand en geen .config bestand? Met de ConfigurationManager kan je die ook eenvoudig uitlezen?
  • makkelijker handmatig te bewerken
  • werkt ook makkelijk op andere platformen
  • lange traditie
  • eenvoudiger (geen echte hiërarchie)
  • meer overzicht als platte tekst
  • sneller (weinig verschil)
  • minder ruimte nodig (weinig verschil)
  • backward-compatible (hier niet van toepassing)
  • ik wilde even laten zien hoe een parser eruit ziet (onzin-reden)
  • sommige dingen, zoals multi-lines, kunnen al gelijk niet in een .ini bestand (jawel, een nadeel als voordeel ;))
Maar dit draadje lijkt hier misschien ook wel op ;)

[ Voor 11% gewijzigd door pedorus op 11-09-2008 09:21 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
En ondertussen verouderd / obsolete.

https://fgheysels.github.io/


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
whoami schreef op donderdag 11 september 2008 @ 09:00:
[...]
En ondertussen verouderd / obsolete.
Hoewel ik het eens ben dat iets als "lange traditie" geen argument is, vind ik dit wel weer erg kort door de bocht. Een ini bestand is een stuk makkelijker leesbaar dan een xml bestand, zeker voor beheerders. Dat wij devvers nu eenmaal in xml onze boodschappen doen, wil nog niet zeggen dat we alleen met onszelf rekening te houden hebben.

Voor key-value settings ben ik persoonlijk ook eerder geneigd om een ini-bestand samen te stellen.
Wordt het ingewikkelder dan dat, of is er behoefte om meer semantiek in je initialisatieparameters, of heb je dat config bestand sowieso nodig (bijvoorbeeld voor assembly referenties), dan is er geen enkele reden om terug te grijpen op een ini-bestand.

Kortom, mee gaan met de tijd is alleen zinvol als het een verbetering met zich meebrengt. En verbetering dan wel in de breedste zin van het woord...
Pagina: 1