3

I'm performing a "while" loop in C#, this is going through some records being pulled from a DB. What's the best way to detect/find the last record on the loop? Is this possible?

Here is my code:

    while (sdr.Read())
    {
        //Pull each line from DB
        the_title = sdr["the_title"].ToString();
        the_cats = sdr["the_category"].ToString();
        the_tags = sdr["the_tags"].ToString();
        the_date = sdr["the_date"].ToString();

        //Start file creation
        writer.WriteLine("[");
        writer.WriteLine("\"" + the_title + "\", ");
        writer.WriteLine("\"" + the_cats + "\", ");
        writer.WriteLine("\"" + the_tags + "\", ");
        writer.WriteLine("\"" + the_date + "\", ");
        writer.WriteLine("\"<a href=\\\"#\\\" class=\\\"sepV_a\\\" title=\\\"Edit\\\"><i class=\\\"icon-pencil\\\"></i></a>\"");

        writer.WriteLine("],");

    }
    writer.WriteLine("]");
    writer.WriteLine("}");
    writer.Close();

The problem I'm having is with the last line of code "writer.WriteLine("],");" I need to remove that comma on the last record being pulled from the DB.

thank you

jorame
  • 2,147
  • 12
  • 41
  • 58

5 Answers5

3

Do it the other way around:

bool is_first = true;

while (sdr.Read()) {

    if (is_first) {
        is_first = false;
    } else {
        writer.Write(",");
    }

    // Do your other writes here
}
Sean Bright
  • 118,630
  • 17
  • 138
  • 146
  • It's as efficient as `writer.WriteLine("[");` is. I won't waste time running a benchmark, but I'm fairly confident the difference would be negligible. – Sean Bright Jun 28 '12 at 19:35
  • 1
    I understand branch prediction. And because `is_first` is not unpredictable (it's `true` for the first iteration and `false` for the rest of them), it will not adversely affect performance as you suggest. – Sean Bright Jun 28 '12 at 19:43
2

I would suggest you to just remove the last character. It is the most efficient solution within a loop.

StringBuilder sb = new StringBuilder();

    while (sdr.Read())
    {
       sb.Append("Value");
       ....
    }

if(sb.Length > 0)
{
sb.Remove(sb.Length - 1, 1)
}
var result = sb.ToString();
Nas
  • 1,063
  • 2
  • 9
  • 22
0

Another approach that should work:

List<String> bufferList = new List<String>();
while (sdr.Read())
{
    //Pull each line from DB
    the_title = sdr["the_title"].ToString();
    the_cats = sdr["the_category"].ToString();
    the_tags = sdr["the_tags"].ToString();
    the_date = sdr["the_date"].ToString();

    StringBuilder tempSb = new StringBuilder();
    tempSb.AppendLine();

    //Start file creation
    tempSb.AppendLine("[");
    tempSb.AppendLine("\"" + the_title + "\", ");
    tempSb.AppendLine("\"" + the_cats + "\", ");
    tempSb.AppendLine("\"" + the_tags + "\", ");
    tempSb.AppendLine("\"" + the_date + "\", ");
    tempSb.AppendLine("\"<a href=\\\"#\\\" class=\\\"sepV_a\\\" title=\\\"Edit\\\"><i class=\\\"icon-pencil\\\"></i></a>\"");
    tempSb.AppendLine(("]");

    bufferList.Add(tempSb.ToString());

}

String.Join(",", bufferList);
J.Hudler
  • 1,238
  • 9
  • 26
0

Yet another approach

if(sdr.Read()) {
    while (true) {
        ...
        writer.WriteLine("[");  
        ...
        if (!sdr.Read()) {
            writer.WriteLine("]"); 
            break;
        }
        writer.WriteLine("],");  
    }
}
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
-1

You can't know the last (up until you've reached/passed it), but you can know the first. You can modify your code as:

bool isFirst = true;
while (sdr.Read())
{
    if (isFirst) isFirst = false;
    else writer.WriteLine(",");

    //Pull each line from DB
    the_title = sdr["the_title"].ToString();
    the_cats = sdr["the_category"].ToString();
    the_tags = sdr["the_tags"].ToString();
    the_date = sdr["the_date"].ToString();

    //Start file creation
    writer.WriteLine("[");
    writer.WriteLine("\"" + the_title + "\", ");
    writer.WriteLine("\"" + the_cats + "\", ");
    writer.WriteLine("\"" + the_tags + "\", ");
    writer.WriteLine("\"" + the_date + "\", ");
    writer.WriteLine("\"<a href=\\\"#\\\" class=\\\"sepV_a\\\" title=\\\"Edit\\\"><i class=\\\"icon-pencil\\\"></i></a>\"");

    writer.Write("]");
}
writer.WriteLine();

Else, to avoid the check in every instance of the loop, you could use:

var sb = new StringBuilder();
while (sdr.Read())
{
    //Pull each line from DB
    the_title = sdr["the_title"].ToString();
    the_cats = sdr["the_category"].ToString();
    the_tags = sdr["the_tags"].ToString();
    the_date = sdr["the_date"].ToString();

    //Start file creation
    sb.AppendLine("[");
    sb.AppendLine("\"" + the_title + "\", ");
    sb.AppendLine("\"" + the_cats + "\", ");
    sb.AppendLine("\"" + the_tags + "\", ");
    sb.AppendLine("\"" + the_date + "\", ");
    sb.AppendLine("\"<a href=\\\"#\\\" class=\\\"sepV_a\\\" title=\\\"Edit\\\"><i class=\\\"icon-pencil\\\"></i></a>\"");

    sb.AppendLine("],");
}
if (sb.Length > 0)
{
    // Write result, sans characters for last newline (Environment.NewLine) and comma.
    writer.WriteLine(sb.ToString(0, sb.Length - (Environment.NewLine.Length + 1));
}

EDIT: Made clipping length dynamic by using Environment.NewLine.Length.

Mike Guthrie
  • 4,029
  • 2
  • 25
  • 48
  • I need to keep that comma on every block of lines, except on the last one. Would this do it for me?? – jorame Jun 28 '12 at 19:39
  • @jorame Sorry, I forgot the comma. Fixed, now. I'd need to double-check that `Length - 2` is the correct amount to clip off, but otherwise yes, this will do it. – Mike Guthrie Jun 28 '12 at 19:42