4

I am really new to Programming and I just started and learned some basics for C#. I just tried to write a method that checks if some special chars are NOT included in a string. My result is this code:

static string GetUnused(string s)
{
    /*
     *  Propably will get confused if s contains '#' char... how2fix?
     */
    char[] signs = { '!', '§', '$', '%', '&', '/', '(', ')', '=', '?' };
    foreach (char c in s)
    {
        if (c == '!') signs[0] = '#';
        if (c == '§') signs[1] = '#';
        if (c == '$') signs[2] = '#';
        if (c == '%') signs[3] = '#';
        if (c == '&') signs[4] = '#';
        if (c == '/') signs[5] = '#';
        if (c == '(') signs[6] = '#';
        if (c == ')') signs[7] = '#';
        if (c == '=') signs[8] = '#';
        if (c == '?') signs[9] = '#';
    }
    string ret = string.Empty;
    foreach (char x in signs)
    {
        if (x == '#') ret += "";
        else ret += x;
    }
    return ret;

but I am pretty sure that is not a good solution to my Problem... How do I mange to solve this in a more elegant way? Thank you for your Answers.

Salah Akbari
  • 36,933
  • 10
  • 58
  • 91
Tomas Wilson
  • 149
  • 1
  • 5

3 Answers3

3

You could use Except:

private static string GetUnused(string s)
{
    char[] signs = {'!', '§', '$', '%', '&', '/', '(', ')', '=', '?'};
    var ret = signs.Except(s);
    return String.Join("",ret);
}
Salah Akbari
  • 36,933
  • 10
  • 58
  • 91
  • A matter of OP choice, `signs` could now be a `string` of those characters, i.e. `return string.Join("", "!§$%&/()=?".Except(s))` – weston Jun 10 '16 at 12:50
  • I think `string.Concat` is even cleaner than `.Join` http://stackoverflow.com/a/11654221/360211 Though `new String(ret.ToArray())` is also an option and it's faster and argubally just as clean. – weston Jun 12 '16 at 06:39
0

If you stored signs as a list<char> you could use RemoveAll to remove any item that exists in the parameter of the method like this:

static string getunused(string param)
{
    list<char> signs = new list<char>(){ '!', '§', '$', '%', '&', '/', '(', ')', '=', '?' };
    signs.removeall(c => param.contains((c.tostring())));
    return new string(signs.toarray());
}
Tim Ashton
  • 426
  • 6
  • 15
0

Yet another answer

static string GetUnused(string s)
{
    char[] signs = { '!', '§', '$', '%', '&', '/', '(', ')', '=', '?' };
    var set = new HashSet<char>(signs);

    foreach (char c in s)
        set.Remove(c);

    return string.Concat(set);
}

HashSet is very fast.

If the input parameter can be very large then next version will be even more profitable, in some cases

static string GetUnused(string s)
{
    char[] signs = { '!', '§', '$', '%', '&', '/', '(', ')', '=', '?' };
    var set = new HashSet<char>(signs);

    foreach (char c in s)
    {
        set.Remove(c);
        if (set.Count == 0)
            return string.Empty;
    }
    return string.Concat(set);
}
Alexander Petrov
  • 11,401
  • 2
  • 15
  • 45
  • Suggest you look at the implementation of [`Except`](http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,e289e6c98881b2b8) (hint, it uses a set) – weston Jun 10 '16 at 14:19