www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - trouble with associative Arrays

reply atzensepp <webwicht web.de> writes:
Hello,

I am new with D and want to convert a c program for a csv file 
manipulation with exhaustive dynamic memory mechanics to D .

When reading a CSV-file line by line I would like to create an 
associative array to get the row values by the value in the 
second column.
Although I save the rows in an array (to get different pointers 
to the values) the program below always gives the last row.
I am sure someone could help.

     thanks


     void main( string args[])
     {
         auto file = File("transpatch2_orig.csv"); // Open for 
reading
         auto range = file.byLine();
         // Print first three lines
         foreach (line; range.take(1))
             writeln(line);
         auto i=0;

         char [][] [string] orgids;
         char [][][] rows;
         foreach (line; range)
         {
             if (!line.empty)
             {
                // auto row = line.split(";");
                 rows ~= (line.split(";"));
                 string word = rows[$ - 1][1].idup;
                 if(word.length>0 && word[0] == '\"')
                         word= word[1 .. $-1];
                 orgids[word.idup]=rows[$ - 1];
                 i++;
             }
         }

         writeln( orgids.length);
         writeln( args[1],orgids[args[1]]);
         writeln( args[2],orgids[args[2]]);
         writeln("Lines: ",i);
     }
Jan 20
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Sat, Jan 20, 2024 at 02:33:24PM +0000, atzensepp via Digitalmars-d-learn
wrote:
 Hello,
 
 I am new with D and want to convert a c program for a csv file manipulation
 with exhaustive dynamic memory mechanics to D .
 
 When reading a CSV-file line by line I would like to create an associative
 array to get the row values by the value in the second column.
 Although I save the rows in an array (to get different pointers to the
 values) the program below always gives the last row.
[...] Because .byLine reuses its line buffer. You want .byLineCopy instead. T -- Everybody talks about it, but nobody does anything about it! -- Mark Twain
Jan 20
parent reply atzensepp <webwicht web.de> writes:
Thank you T for your hint. This worked perfectly
On Saturday, 20 January 2024 at 14:44:49 UTC, H. S. Teoh wrote:
 Because .byLine reuses its line buffer.  You want .byLineCopy 
 instead.
The section looks now simpler although I guess that there are more appropriate mechanisms available (csvreader): string [] orgids[string]; foreach (line; range) { if (!line.empty) { auto row = line.split(";"); string word = row[1]; if(word.length>0 && word[0] == '\"') word= word[1 .. $-1]; orgids[word]=row; i++; } }
Jan 20
parent Renato <renato athaydes.com> writes:
On Saturday, 20 January 2024 at 15:16:00 UTC, atzensepp wrote:
 The section looks now simpler although I guess that there are 
 more appropriate mechanisms available (csvreader):

     string [] orgids[string];
     foreach (line; range)
     {
         if (!line.empty)
         {
             auto row = line.split(";");
             string word = row[1];
             if(word.length>0 && word[0] == '\"')
                     word= word[1 .. $-1];
             orgids[word]=row;
             i++;
         }
     }
Maybe a bit more readable: ```d import std.string : strip, split; string [] orgids[string]; foreach (line; range) { if (line.empty) continue; auto row = line.split(";"); auto word = row[1].strip("\""); orgids[word] = row; i++; } ```
Jan 20