1

I have a method that to remove the description word base on the string, but I believe that there is more efficient way to do this.

The iMonster can be like fat orc rogue, and I want to remove the fat.

    private static string[] _adjectives = { "angry", 
                                            "big", 
                                            "fat", 
                                            "happy",
                                            "large", 
                                            "nasty", 
                                            "fierce", 
                                            "thin",
                                            "small", 
                                            "tall", 
                                            "short" };

    private static string RemoveMonsterAdjective(string iMonster)
    {
        foreach (string adjective in _adjectives)
        {
            if (iMonster.Contains(adjective))
            {
                iMonster = iMonster.Replace(adjective, "").Trim();
                break;
            }
        }
        return iMonster;
    }

hopefully someone can help me. Thanks in advance.

7
  • 2
    Looks OK. Is this really a bottleneck for you? Commented Jan 5, 2013 at 17:35
  • 5
    Your code looks OK. Only one thing: because of the break if the imonster is a "big fat nasty orc rogue" you will get "fat nasty orc rogue" as the result. Commented Jan 5, 2013 at 17:36
  • @lakedoo As long you manage your adjectives array, it seems fine. But you would need a way to elminitae multiple adjectives like removing multiple delimiters ;) +1 @nemesv Commented Jan 5, 2013 at 17:38
  • thanks, good point about multiple adjectives, I will fix that. Commented Jan 5, 2013 at 17:43
  • (relevant only if break is removed) String is immutable so if iMonster is big and _adjectives is large and could result in multiple hits it may help to use StringBuilder or StringBuffer to yield a heavily mutated result. Although it will increase complexity. Commented Jan 5, 2013 at 17:43

2 Answers 2

5

You can do all replacements in a single call using regular expressions, like this:

return Regex.Replace(
    iMonster,
    @"\b(angry|big|fat|happy|...)\b",
    ""
).Trim();

The idea behind this approach is to construct a regular expression that matches any adjective as a single word (so "bigot" would not be matched, while "big" would be matched), and replace that word with an empty string.

Here is a demo on ideone.

Sign up to request clarification or add additional context in comments.

4 Comments

I'd be interested to see a benchmark of this and the looping String.Replace. I would suspect that as the input gets longer and contains more adjectives, the regex is going to overcome its initial overhead and end up faster (less reallocation).
This solution leaves spaces which were between words
@lazyberezovsky Fair enough. ;-)
It seems that the regex, while simpler, is slower even for long strings: ideone.com/wWuexS
4

Another possible short solution is:

var words = iMonster.Split(' ');
return string.Join(" ", words.Except(_adjectives));

I've done some profiling and compared the various solutions.

With input fat angry orc happy rogue and 1000000 iterations:

00:00:01.8457067 lakedoo
00:00:01.9772477 Eve
00:00:04.3859120 dasblinkenlight

Need to mention that I adapted dasblinkenlight's solution to have all the adjectives in the regex.

EDIT: corrected lakedoo's method by removing the break.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.