Thread overview
trouble with associative Arrays
Jan 20
atzensepp
Jan 20
atzensepp
Jan 20
Renato
January 20

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);
}
January 20
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
January 20

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++;
    }
}
January 20

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:

 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++;
 }