-1

I have working example without the conditional here.

public string RenderPostTags(DMCResultSet resultSet)
{
    string output = "";
    string filterForm = RenderFilterForm(resultSet);
    string pagination = RenderPagination(resultSet);
    List<XElement> items = resultSet.items;
    foreach(XElement i in items)
    {
        string tags = "";
        if (i.Element("tags") != null) 
        {
            foreach(string tag in i.Element("tags").Elements("tag"))
            {
                tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag + "</a>"; 
            }
        }
        output += tags;
    }
    return  output;
}

I know just putting a count on it wont work but I've tried several different methods and they haven't worked for me. Could be a syntactical error I'm a total C# noob.

But I need to output adjusted html using a if else conditional similar to this

public string RenderPostTags(DMCResultSet resultSet){
            string output = "";
            string filterForm = RenderFilterForm(resultSet);
            string pagination = RenderPagination(resultSet);
            List<XElement> items = resultSet.items;
            foreach(XElement i in items){
                string tags = "";
                if (i.Element("tags") != null) {
                    int count = 1;
                    int total = i.Element("tags").Elements("tag").Count;
                    foreach(string tag in i.Element("tags").Elements("tag")) {
                        if(count == total){
                            tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag + "</a>"; 
                            count++;
                        }else{
                            tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag +","+ " " + "</a>";  
                            count++;
                        }
                    }
                }
                output += tags;
            }
            return  output;
        }

Methods I have tried can be found on this thread. Foreach loop, determine which is the last iteration of the loop

Thank you for any assitance.

Somosfeer
  • 72
  • 8
  • When not on the last interaction of the loop I need to add spacing and comma to my HTML output. The issue is I'm having difficulty setting up the mechanism to monitor when I'm iterating through the final item. Hopfully that helps – Somosfeer Jul 28 '20 at 23:47
  • counter will not be changed unless you put counter++; inside of foreach loop. – Arphile Jul 28 '20 at 23:48
  • 3
    Are you trying to get the count inside the loop? If so why not just use good old `for` loops? – Sach Jul 28 '20 at 23:48
  • 1
    OK, so declare a `count` variable outside the loop and set it to 1. Get the total count of items outside the loop by `var total = items.Count()`. Then inside the loop at every iteration increase the count by 1, and see `if(count == total)` – Sach Jul 28 '20 at 23:50
  • OK I've gone ahead and updated the code above to make it readable. Thank you for your help thus far. – Somosfeer Jul 29 '20 at 00:11
  • You should also use mutable [StringBuilder](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder?view=netcore-3.1) instead. Basically `string` is immutable and you should avoid something like `tags +=` specially in a loop. – Coding Enthusiast Jul 29 '20 at 06:16

3 Answers3

1

As @Sach said, use the for loop instead of foreach.

string output = "";
List<XElement> items = new List<XElement>();
foreach (XElement i in items)
{    
    string tags = "";
    if (i.Element("tags") != null && i.Element("tags")?.Elements("tag") != null)
    {
        List<XElement> tagItems = i.Element("tags").Elements("tag").ToList();
        if (tagItems == null) continue;
        for (int j = 0; j < tagItems.Count(); j++)
        {
            XElement tag = tagItems[j];
            if (j == i.Element("tags")?.Elements("tag").Count() - 1)
            {
                tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag + "</a>";
            }
            else
            {
               tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag + "," + " " + "</a>";
            }
        }
    }
    output += tags;
}
quaabaam
  • 1,808
  • 1
  • 7
  • 15
1

You can write your foreach loop like this to capture both conditions. You can use condition ? true : false to write either/or based on the last item in the collection.

int counter = 1; // Start with 1 since we are using != later on.
int totalRecords = i.Element("tags").Elements("tag").Count();
foreach (string tag in i.Element("tags").Elements("tag"))
    tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag + counter++ != totalRecords ? ", "  : string.Empty + "</a>";

Above is equivalent to

if (i.Element("tags") != null)
{
    int counter = 1;
    int totalRecords = i.Element("tags").Elements("tag").Count();
    foreach (string tag in i.Element("tags").Elements("tag"))
    {
        if (counter++ == totalRecords)
        {
            tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag + "</a>";
        }
        else
        {
            tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag + ", " + "</a>";
        }
    }
}

Make a note that IEnumerable does not have a Count property but have a method Count().

Jawad
  • 11,028
  • 3
  • 24
  • 37
0

So maybe for namespace reasons the count method would not solve my issue. However after some toil this solution worked perfectly. Thankyou for those to helped me get to this solution.

public string RenderPostTags(DMCResultSet resultSet){
            string output = "";
            string filterForm = RenderFilterForm(resultSet);
            string pagination = RenderPagination(resultSet);
            List<XElement> items = resultSet.items;

            foreach(XElement i in items){
                string tags = "";
                if (i.Element("tags") != null) {
                    foreach(string tag in i.Element("tags").Elements("tag")){
                        if(tags != "") tags += ", &nbsp; ";
                        tags += "<a href=\"?tag=" + HttpUtility.UrlEncode(tag) + "\">" + tag  +"</a>"; 
                    }
                }
                output += tags;
            }
            return  output;
        }
Somosfeer
  • 72
  • 8