Question

string to build up using keyvaluepair is like this: "name1=v1&name2=v2&name3=v3"

what i am doing:

var sb = new StringBuilder();

foreach (var name in nameValues)
{
            sb.AppendFormat("{0}={1}&", name.Key, name.Value);
 } 

//remove last '&' sign, this is what i think is ugly
sb.ToString().Remove(lastIndex);

any elegant way to avoid the last removal statement of '&' sign?

Was it helpful?

Solution

var joined =
    String.Join("&", nameValues.Select(n => n.Key + "=" + n.Value).ToArray());

Given that we're not concatenating to one big string (we're producing many small strings) concatenation carries no performace penalties in this case. And in .NET strings are length prefixed anyway so the whole concatenation performance issue is less relevant than in C. String.Join() is very fast as well, faster than StringBuilder.

TLDR: Use String.Join()

OTHER TIPS

Take a look here: How to build a query string for a URL in C#?; Quoting:

private string ToQueryString(NameValueCollection nvc)
{
    return "?" + 
        string.Join("&", 
            Array.ConvertAll(
                nvc.AllKeys, 
                key => String.Format("{0}={1}", HttpUtility.UrlEncode(key),
                HttpUtility.UrlEncode(nvc[key]))));
}
foreach (var name in nameValues)
    {
        if (sb.Length > 0) sb.Append("&");
                sb.AppendFormat("{0}={1}", name.Key, name.Value);
     }

Just add "&" when needed, do not remove it from end.

Here's another approach which I've sometimes used:

var sb = new StringBuilder();
string prefix = "";
foreach (var name in nameValues)
{
    sb.Append(prefix);
    prefix = "&";
    sb.AppendFormat("{0}={1}", name.Key, name.Value);
}

It's just a way of prepending & before every pair other than the first one without using a conditional test.

If you want to use your original idea of trimming the StringBuilder by the way, I'd suggest the following code instead:

sb.Length--; // Remove the last character
return sb.ToString();

I tend to use this, utilising the fact you can truncate a string builder with a decrement on the length property:

var sb = new StringBuilder();

foreach (var name in nameValues)
{
    sb.AppendFormat("{0}={1}&", name.Key, name.Value);
} 

if (sb.Length > 0) sb.Length--;

Well at least you can remove the & sign before the ToString() call by doing --sb.Length;

var sb = new StringBuilder();

sb.AppendFormat("{0}={1}", nameValues[0].Key, nameValues[0].Value);

for (int i = 1; i < nameValues.Count; i++)
{
        sb.AppendFormat("&{0}={1}", nameValues[i].Key, nameValues[i].Value);
} 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top