Search code examples
c#liststreamreader

Reading into list and picking specific numbers


A request came in for an app written a long time ago, they wanted another column on an existing datagridview with current drilling times. These times come from a file that machines read and run. Below is an example of a file.

Machine Program

Now the numbers there looking for are the ones with an S. Now, the very first number is the line number. The line number needs grabbed too as the time's need to match up with the line. So I have to read this into a list, grab the line number and then the associated "s" time number. I will be adding these "s times" to an existing table which already has the line numbers so I'll add these "s times" to a new column next to the corresponding line number. I'm a bit stuck here.

Any help is appreciated.

I know I can read everything in like this

         string f = ("//dnc/WJ/MTI-WJ/" + cboPartProgram.Text);

        List<string> lines = new List<string>();

        using (StreamReader r = new StreamReader(f))
        {
            // Use while != null pattern for loop
            string line;
            while ((line = r.ReadLine()) != null)
            {
                lines.Add(line);
            }
        }

But once in a list I need to ignore lines that start with an apostrophe " ' ", then take only the first line number "1, 2, 3" etc for however many there are and then the "s" number of that line.

So that I'm left with:

1    2.75
2    2.5
3    2

...etc

Now, on the database there is a program table. with columns

Program  Line  Time
Program1  1    
Program1  2
Program1  3
Program1  4

etc

So the "s" times will be added to the time column of the existing table. But the "s" times taken from line 1,2,3,4 and so on will coincide with the line column of the table.

So, the final end result in this example would be

Program  Line  Time
Program1  1    2.75
Program1  2    2.5
Program1  3    2

UPDATE

I'm not sure if the edited code to cover the lines w/out the sTime work yet because I'm ran into an issue recently. There is a datagridview that populates the columns from a list filled from a sql statement. I've added a column for the sTime (turns out I may not need the line# so you'll notice I removed that) however I need to incorporate my loop from sTime into the loop that is occurring for the list that is also populating the dgv. Now I've tried to incorporate this in a couple of different ways however what happens is either the very last sTime is use for all 80 entries of the dgv (as the example below does) or if I move the " } " brackets around some and combine them then uses the first sTime to create 80 entries of dgv, then the 2nd sTime to create 80 entries of the dgv. So instead of 80 entries in dgv with each individual sTime next to it, you end up with 6,400 entries in dgv 80x80. so I'm not sure how to combine these 2 to work.

        var sLines = File.ReadAllLines("//dnc/WJ/MTI-WJ/" + cboPartProgram.Text)
             .Where(s => !s.StartsWith("'"))
             .Select(s => new
             {
                 SValue = Regex.Match(s, "(?<=S)[\\d.]*").Value
             })
             .ToArray();

        string lastSValue = "";
        foreach (var line in sLines)
        {
            string val = line.SValue == string.Empty ? lastSValue : line.SValue;
            lastSValue = val;
        }



            foreach (WjDwellOffsets offset in dwellTimes)
            {
                origionalDwellOffsets.Add(offset.dwellOffset);

                dgvDwellTimes.Rows.Add(new object[] { offset.positionId, lastSValue, offset.dwellOffset, 0, offset.dwellOffset, "Update", (offset.dateTime > new DateTime(1900, 1, 1)) ? offset.dateTime.ToString() : "" });
                DataGridViewDisableButtonCell btnCell = ((DataGridViewDisableButtonCell)dgvDwellTimes.Rows[dgvDwellTimes.Rows.Count - 1].Cells[5]);
                btnCell.Enabled = false;
            }

Solution

  • If your only condition is to keep the lines that have an "S" in them, and if that data sample is indicative of the overall line pattern, then this is quite simple (and you can use Regex to further filter your results):

    var sLines = File.ReadAllLines("filepath.txt")
                     .Where(s => !s.StartsWith("'") && s.Contains("S"))
                     .Select(s => new 
                     { 
                         LineNumber = Regex.Match(s, "^\\d*").Value,
                         SValue = Regex.Match(s, "(?<=S)[\\d.]*").Value
                     })
                     .ToArray();
    
    // Use like this
    foreach (var line in sLines)
    {
        string num = line.LineNumber;
        string val = line.SValue;
    }
    

    To maintain all lines and just have relevant information on some, this method can be a bit tweaked, but it will also require a bit of some outside processing.

    var sLines = File.ReadAllLines("filepath.txt")
                     .Where(s => !s.StartsWith("'"))
                     .Select(s => new 
                     { 
                         LineNumber = Regex.Match(s, "^\\d*").Value,
                         SValue = Regex.Match(s, "(?<=S)[\\d.]*").Value
                     })
                     .ToArray();
    
    // Use like this
    string lastSValue = "";
    foreach (var line in sLines)
    {
        string num = line.LineNumber;
        string val = line.SValue == string.Empty ? lastSValue : line.SValue;
    
        // Do the stuff
    
        lastSValue = val;
    }