1

I have an enum with six distinct values:

One Two Three Four Five Six

which is filled from a config file (i.e. string)

Let's say someone writes into the config file any of the values

  • On
  • one
  • onbe

or other common misspellings/typos, I want to set the most similar value from the enum (in this case, "One") instead of throwing up.

Does C# have something like that builtin or will I have to adapt an existing Edit Distance algorithm for C# and hook that into the enum?

Alexander
  • 19,906
  • 19
  • 75
  • 162
  • [this](http://stackoverflow.com/a/1034655/2030635) answer on measuring similarity between strings might help. – MX D May 11 '16 at 09:02
  • So if I understand both comment and answer correctly, enums do not have anything like that builtin. That's what I wanted to know. – Alexander May 11 '16 at 09:04
  • 3
    Personally, I think it would be better if you threw an error in this instance. From a user perspective I'd be very confused if my typo magically validated. There is `Enum.Parse()` which would succeed for the lowercase `"one"` e.g. `Enum.Parse(typeof(myenum), "one", true)` as you can tell it to ignore case. Your best bet is to implement the levinshtein distance algorithm as posted below and try to match the input before parsing to your enum value. Again, I would recommend against doing this though. – DGibbs May 11 '16 at 09:05

1 Answers1

1

You can use Levinshtein distance, this tells us the number of edits needed to turn one string into another:

so just go through all values in your enum and calculate Levinshtein distance:

private static int CalcLevenshteinDistance(string a, string b)
{
    if (String.IsNullOrEmpty(a) || String.IsNullOrEmpty(b)) return 0;

    int lengthA = a.Length;
    int lengthB = b.Length;
    var distances = new int[lengthA + 1, lengthB + 1];
    for (int i = 0; i <= lengthA; distances[i, 0] = i++) ;
    for (int j = 0; j <= lengthB; distances[0, j] = j++) ;

    for (int i = 1; i <= lengthA; i++)
        for (int j = 1; j <= lengthB; j++)
        {
            int cost = b[j - 1] == a[i - 1] ? 0 : 1;
            distances[i, j] = Math.Min
                (
                Math.Min(distances[i - 1, j] + 1, distances[i, j - 1] + 1),
                distances[i - 1, j - 1] + cost
                );
        }
    return distances[lengthA, lengthB];
}
Alex Vazhev
  • 1,363
  • 1
  • 18
  • 17
  • So if I understand both comment and answer correctly, enums do not have anything like that builtin. That's what I wanted to know. – Alexander May 11 '16 at 09:04
  • I have not faced with it. I absolutely agree with @DGibbs, it would be better to throw an error. For example, which enum value you would like to choose if you have "Onc" as input string (On or one)? But if you want to implement your functionality very much, you can use Levinshtein distance ) – Alex Vazhev May 11 '16 at 09:09