Home > front end >  Why am I getting unexpected results with StringBuilder and .replace?
Why am I getting unexpected results with StringBuilder and .replace?

Time:02-05

I'm trying to find specific criteria (dogsWildcard, catsWildcard, birdsWildcard) in a string (wildCard) and then modify the string so it has a number associated with the criteria.

For example, I want the cold below to return: "*DOGS 111 *CATS 222 *BIRDS 333"

However, it's returning something that looks like: "*CATS *DOGS 222 *BIRDS*DOGS 111 *EVENTS *BIRDS*BIRDS *DOGS *CATS 333"


public string ProcessMerchantRefNbr()
{
var wildCard = "*DOGS *CATS *BIRDS";

string catsWildcard = "*CATS";
string dogsWildcard = "*DOGS";
string birdsWildcard = "*BIRDS";

var dogId = "111";
var catId = "222";
var birdId = "333";

var strMerchantRefNbr = new StringBuilder();

if (wildCard.Contains(catsWildcard)) strMerchantRefNbr.Append($"{catsWildcard} {wildCard.Replace(catsWildcard, catId)}");

if (wildCard.Contains(dogsWildcard)) strMerchantRefNbr.Append($"{dogsWildcard} {wildCard.Replace(dogsWildcard, dogId)}");

if (wildCard.Contains(birdsWildcard)) strMerchantRefNbr.Append($"{birdsWildcard} {wildCard.Replace(birdsWildcard, birdId)}");

return strMerchantRefNbr.ToString()
}

What am I doing wrong?

CodePudding user response:

Simply you don't need the Replace.

var strMerchantRefNbr = new StringBuilder();

if (wildCard.Contains(catsWildcard)) strMerchantRefNbr.Append($"{catsWildcard} {catId} ");
if (wildCard.Contains(dogsWildcard)) strMerchantRefNbr.Append($"{dogsWildcard} {dogId} ");
if (wildCard.Contains(birdsWildcard)) strMerchantRefNbr.Append($"{birdsWildcard} {birdId} ");

// strMerchantRefNbr.ToString(): *CATS 222 *DOGS 111 *BIRDS 333 

CodePudding user response:

try this

public string ProcessMerchantRefNbr()
{
    var wildCard = "*DOGS *CATS *BIRDS";
    string[,] replacements = new string[,] { { "*DOGS", "*CATS", "*BIRDS" }, 
                                             { "111", "222", "333" } };

    var sb = new StringBuilder(wildCard);

    for (var i = 0; i <= replacements.GetLength(0); i  )
    {
        var wc = replacements[0, i];
        var num = replacements[1, i];

        sb.Replace(wc, wc   " "   num);
    }

    return sb.ToString();
}

result

*DOGS 111 *CATS 222 *BIRDS 333

or I would make it even more flexible creating something like this

string[,] replacements = new string[,] { { "*DOGS", "*CATS", "*BIRDS" }, 
{ "*DOGS 111 ...", "*CATS 222 ...", "*BIRDS 333 ..." } };

CodePudding user response:

You are appending the string with one replacement for every condition which resolves to true. Actually you can omit the checks - append the original string to the builder and use Replace on it:

var strMerchantRefNbr = new StringBuilder();
strMerchantRefNbr.Append(wildCard);
strMerchantRefNbr.Replace(catsWildcard, $"{catsWildcard} {catId}");
strMerchantRefNbr.Replace(dogsWildcard, $"{dogsWildcard} {dogId}");
strMerchantRefNbr.Replace(birdsWildcard, $"{birdsWildcard} {birdId}");

This code can be improved by creating wildcard -> replacement pairs and using cycle. For example using value tuples:

var replacements = new List<(string Wildcard, string Replacement)> 
{
    ("*CATS", "111"),
    ("*DOGS", "222"),
    ("*BIRDS", "333")
};

var strMerchantRefNbr = new StringBuilder();
strMerchantRefNbr.Append(wildCard);
foreach(var (wc, replacement) in replacements)
{
    strMerchantRefNbr.Replace(wc, $"{wc} {replacement}");
}
  •  Tags:  
  • Related