in arrays...

Hi,

I'm trying to read a text file, somewhat like this:

#15-07-2001
sdkfhksdfhsdc
cskjmcdfcsd
#13-12-1999
asljkdaksjxd
dcjdvf

etc...

I want to save the dates... so I put up something like this:

string line;
string date;
StreamReader sr = new StreamReader(...);
while((line=sr.ReadLine()) != null)
{
     if(line.StartsWith("#"))
     {
          line = line.Remove(0,1);
          date = line;
     }
}
sr.Close();

ofcourse this will only return the last of the dates... so I think I should use an array of strings. How can I do that, if I don't previously know the number of dates in the file

Thanks


Answer this question

in arrays...

  • Bill Foust-DAI

    thanks, but then how can I access both stringitems and dates with the array list returned
  • ismail-marmoush

    explained badly... sorry. What I can't find is the method Items that, acordding to Avi, belongs to ArrayList.
  • LittleRascal

    hey... thanks a lot! but just one final thing: that code doesn't allow me to separate each text... and tell which one belongs to which date...
  • cdaniele

    You can use an ArrayList:

    ArrayList results = new ArrayList();
    ...
    ArrayList.Add(line);

    or, if you just want to add strings, you can use a StringCollection.

    These classes are in the System.Collections and System.Collections.Specialized namespace respectively.

  • Ettore

    You could use an ArrayList instead of an array.  You do not have to specifiy the number of items you will be adding to an ArrayList as you do with Arrays.
  • GaryUSA

    al is an ArrayList ...  Avi explains that in his post:
    Quote-
    One thing to note here. The first line that does "al.Items[...]" will initially not compile. The reason is because "al" was defined as a local variable in the previous function we were working on. In order to be able to access it from the event handler (in fact, from any method within your class/page), you need to make it a member of the main page class. 
    -Quote

  • Darrell

    hmmm... thanks... just don't know where you got al.Items... and I can't find any similar method...
  • Youri Pikulin

    well yes, you're right! But i'll explain my situation: I have two controls: a combo box and a textbox. If one changes the selected index of the combo box (where the items are the dates), the textbox text should be the corresponding text to that date... So another question... how can I get the DateInformation's StringItems for this certain index (comboBox.SelectedIndex)

    thanks again

  • Liz____9

    You could try using an ArrayList. The list will automatically expand as you add new dates.
  • Mangix

    FreJa,

    Now you're getting into a more complex question of saving general purpose data in RAM. The nicest way to do this (one that will allow you to easily adapt to new formats of the text file) is to create a class that can store all the data associated with one date, then create a list of objects of that class.

    I'm not sure whether each date necessarily has 2 strings, or any number - Let's assume any number. So your class will look something like this (this code may not compile, I'm just going off the top of my head):


    // This class will store a date, and N strings to go with it.
    class DateInformation
    {
      public string Date;
      public ArrayList StringItems;   // A list of strings

      // The constructor will initialize the date
      public DateInformation( string d )
      {
        Date = d;
        StringItems = new ArrayList();
      }
    }


    Then, in your code above, instead of adding a string to the main ArrayList, you would add a whole "DateInformation" object. If the line is not a date marker, you would just add it as a string item to the existing class. Something along these lines:


    DateInformation CurDate = null;
    while ( (line=sr.ReadLine()) != null)

      if ( line.StartsWith("#") )
      {
        CurDate = new DateInformation( line.Remove(0,1) );
        al.Add( CurDate ); 
      }
      else
      {
        if ( CurDate != null )
          CurDate.StringItems.Add( line );

        // If CurDate == null at this point, then your file is probably in a bad format.
      }
    }


    Does this help

  • RomuloChile

    I'm not sure I follow... but I'll try :)

    If I understand your file format correctly, it's like this:



    DATE
    text
    ...
    text
    DATE
    text
    ...
    text
    etc...


    Where all the text under a given date "belongs" to that date. Let's name a date together with its owned text a "chunk". So you have a file with many chunks.

    If that's the case, then the code I showed will create a DateInformation object for each chunk in the file. That DateInformation object contains the date itself in the "Date" member, and the belonging text in the StringItems member.

    So the loop I showed to print it all out will give you each chunk, one after the other, and for each chunk, you'll get the belonging text, in the order it was read.


    So let's say your file looks like this:


    1/1/2003
    sirloin
    prime-rib
    1/2/2003
    tri-tip
    flank


    Then the code will create two DateInformation objects:

    <u>Object1:</u>

    Object1.Date == "1/1/2003"
    Object1.StringItems.Items[0] == "sirloin"
    Object1.StringItems.Items[1] == "prime-rib"


    <u>Object2:</u>

    Object2.Date == "1/2/2003"
    Object2.StringItems.Items[0] == "tri-tip"
    Object2.StringItems.Items[1] == "flank"


    So as you go through the loop, you'll get an object for each iteration, and you know that the members of StringItem necessarily belong to that date. You can do whatever you want with that object, and it will always contain that whole chunk of data, grouped correctly.

    Is that more helpful  I hope I understood the question correctly.
    If not, tell me exactly what you want to do with this data, and I'll try to aim the answer towards that solution.


  • StanScott

    Ah, okay, I see.

    Well, here's a simple solution. It may not be ultra-elegant, but it should work.

    Each item (ListItem) in a combo box has two properties: The text that's displayed (called "Text"), and the value for that text (called "Value"). So what we can do is have the display text be the date itself, and the value be an index pointing to where the DateInformation object is. So when someone selects something, you use the value to look up the object, then grab the StringItems from it.

    So while you're building your main ArrayList ("al"), for each new DateInformation created, also create an entry in the combo box. I'll paste in the original code, and add to it. Note only 3 lines have been added:


    int count = 0;  // NEW LINE: Keep track of the number of items we've added.
    DateInformation CurDate = null;
    while ( (line=sr.ReadLine()) != null)

      if ( line.StartsWith("#") )
      {
        CurDate = new DateInformation( line.Remove(0,1) );
        al.Add( CurDate );
        MyCombo.Items.Add( new ListItem( di.Date, count ) );  // NEW LINE: Add to the Combo
        count++;  // NEW LINE: Increment the item count
      }
      else
      {
        if ( CurDate != null )
          CurDate.StringItems.Add( line );

        // If CurDate == null at this point, then your file is probably in a bad format.
      }
    }


    So now, as you're building your list, you're building your combo box with new ListItems. Each ListItem is given a "Text" value of the date ("di.Date"), and a "Value" value of "count", which is the number of items we've created until now. It also happens to be the index of the current DateInformation object in the big ArrayList, starting at zero. That's the key!

    So now, in your handler for the combo box, you can do this:


    // Get a reference to the DateInformation object
    DateInformation di = al.Items[MyCombo.SelectedValue];

    // Now grab all the text from it, build a string, then put it in a text box:
    string AllText = "";
    foreach ( string si in di.StringItems )
    {
      AllText += si + "\n";
    }

    MyTextBox.Text = AllText;


    The first line of that snippet is the magic. The item "MyCombo.SelectedValue is the value of the item that has been selected. That value will be the Nth item that we added to al, and can hence be used as an index into the ArrayList, which should return a DateInformation object.

    One thing to note here. The first line that does "al.Items[...]" will initially not compile. The reason is because "al" was defined as a <b>local</b> variable in the previous function we were working on. In order to be able to access it from the event handler (in fact, from any method within your class/page), you need to make it a member of the main page class.

    And one final thing: Another way to do this would have been to make each ListItem's value the actual string you want to put into the textbox. I don't like this, because it's very limited. Let's say one day you want to add more properties to each chunk (if your file format changes). Then you won't be able to get at those, because a ListItem can only store one value. But using the value to get a reference to the original DateInformation object, you can easily get at any member of that object. Makes the app much easier to maintain.

    Makes sense

  • Karthigueyane L

    Accessing it is nice and clean. Let's assume the ArrayList is still called "al" from the previous code snippet. What you do is loop through the ArrayList, getting a "DateInformation" object for each iteration.

    For each one of those DateInformation objects, you can then access its members to get the data. The first member ("Date") is a simple string. The rest of the data is in the second member ("StringItems"), so you just loop through that one as well. So we end up with a loop within a loop.

    In this example, I'm just printing each DateInfo to the console, formatted simply.


    foreach ( DateInformation di in al )   // Grab each entry in the main ArrayList
    {
      Console.WriteLine( di.Date );         // Grab & Print the "Date" member

      // For each item in the list of strings, print it out.
      foreach ( string si in di.StringItems )
      {
        Console.WriteLine( "\t" + si );
      }

      // Print an extra space just to leave spaces between each DateInformation
      Console.WriteLine( "\n" );
    }


    Does this help, FreJa

  • Jyri Hujanen

    ok, so this is what I'm doing:

    string line;
    StreamReader sr = new StreamReader(...);
    ArrayList al = new ArrayList(); 
    while((line=sr.ReadLine()) != null) 
    {
    if(line.StartsWith("#")) 
    {
    al.Add(line.Remove(0,1)); 
    }
    }
    sr.Close();
    return(al); 


    but now, how can I save the text that correspond to each date  the onw that is below the date...

  • in arrays...