3

I want to combine/merge/join/whatever a list of enums, so that each item in the unified list will have two fields - the name of the enum item (string Name), and its value (TokensEnum Token):

var tokens = Enum.GetValues(typeof (TokensEnum)); var names = Enum.GetNames(typeof (TokensEnum)); var combined = InTheDarknessBindThem(tokens,names); foreach(var c in combined) MessageBox.Show(string.Format( "Token \"{0}\" value is {1}", c.Name, (int)c.Token)); 

How to write the body of the following method (preferably LINQ-wise)?

InTheDarknessBindThem(IEnumerable<TokensEnum> tokens, IEnumerable<string> names) { /* ... */ } 
4
  • 6
    +1 for creative method names Commented Dec 16, 2013 at 17:09
  • 4
    Why would you just not call ToString() on each value to get the name? There's no need to get the names and values separately. Commented Dec 16, 2013 at 17:09
  • @JonSkeet, that's obvious, but not the point. It's just a simple demonstration for what I want to achieve: the goal is to have a Dictionary<string,TokensEnum> for some kind of parser, and each enum can be decorated with attributes (but doesn't have to..) Commented Dec 16, 2013 at 17:15
  • @Tal: So please give a more representative example. It's not clear how a dictionary fits in here, or what you'd actually have... Commented Dec 16, 2013 at 17:17

2 Answers 2

4

If both lists are in order, you can use the Zip extension method:

tokens.Cast<TokensEnum>().Zip(names, (t, n) => Tuple.Create(t, n)); 

This will return an IEnumerable<Tuple<TokensEnum, string>>.

But as Jon Skeet suggests, in this case, it would probably be easier to do something like this:

Enum.GetValues(typeof(TokensEnum)) .Cast<TokensEnum>() .Select(t => Tuple.Create(t, t.ToString())); 

This will return the same result as above, but it will do it in a single step.

Since you mentioned in your comments that you'd like to have a Dictionary<string, TokensEnum>, you can use something like this to construct it:

Dictionary<string, TokensEnum> myDictionary = Enum.GetValues(typeof(TokensEnum)) .Cast<TokensEnum>() .ToDictionary(t => t.ToString()); 
Sign up to request clarification or add additional context in comments.

3 Comments

Your first answer is what I was looking for! Thanks! The rest are obvious, but I must do some processing before adding them to the dictionary, if at all: attribute-fetching (and acting accordingly) and Regexp manipulations, to name a few..
@Tal You could probably do all (or most) of that in a single linq query as well. But glad I could help.
Indeed, I can probably do it in a single LINQ query (and as yourself, I'm not 100% sure about it..), but as you most likely already know, in terms of readability it's many times better not to. In this case, there's a lot of code inside the foreach that comes afterwards (and that's another reason why I didn't provide the whole code)
1

Why not a dictionary?

var dict = Enum.GetValues(typeof (TokensEnum)) .Cast<TokensEnum>() .ToDictionary(x => x, x => x.ToString()); foreach (var kvp in dict) { Console.WriteLine("Value: {0}, Name: {1}",kvp.Key,kvp.Value); } 

The printout is a bit moot since ToString() is called on value.

I think using enum as key in a dictionary cases boxing.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.