2

I have an enum, and I would like to find all the matching values of the enum that start with the beginning of an incoming string (case insensitive)

Example:

enum Test
{
   Cat,
   Caterpillar,
   @Catch,
   Bat
}

For example, if I specify "cat" to this Linq Query, it would select Test.Cat, Test.Caterpillar, Test.Catch

spender
  • 117,338
  • 33
  • 229
  • 351
Ilan Keshet
  • 514
  • 5
  • 19
  • 2
    `Catch` is a reserved token, so must be preprended with `@`. https://stackoverflow.com/questions/91817/whats-the-use-meaning-of-the-character-in-variable-names-in-c – spender Sep 23 '18 at 01:51
  • Ah oops that was a complete accident... I was using this as an example - (not actual in my code) – Ilan Keshet Sep 23 '18 at 01:53

1 Answers1

4
Enum.GetValues(typeof(Test)) //IEnumerable but not IEnumerable<Test>
    .Cast<Test>()            //so we must Cast<Test>() for LINQ
    .Where(test => Enum.GetName(typeof(Test), test)
                       .StartsWith("cat", StringComparison.OrdinalIgnoreCase))

or if you're really hammering this, you might prepare a prefix lookup ahead of time

ILookup<string, Test> lookup = Enum.GetValues(typeof(Test)) 
    .Cast<Test>() 
    .Select(test => (name: Enum.GetName(typeof(Test), test), value: test))
    .SelectMany(x => Enumerable.Range(1, x.name.Length)
                               .Select(n => (prefix: x.name.Substring(0, n), x.value) ))
    .ToLookup(x => x.prefix, x => x.value, StringComparer.OrdinalIgnoreCase)

so now you can

IEnumerable<Test> values = lookup["cat"];

in zippy O(1) time at the expense of a bit of memory. Probably not worth it!

spender
  • 117,338
  • 33
  • 229
  • 351