Reputation: 26301
Consider the following object:
Controller controller = new Controller()
{
Name = "Test",
Actions = new Action[]
{
new Action() { Name = "Action1", HttpCache = 300 },
new Action() { Name = "Action2", HttpCache = 200 },
new Action() { Name = "Action3", HttpCache = 400 }
}
};
How can I map this object to a dictionary of the following form?
#key# -> #value#
"Test.Action1" -> 300
"Test.Action2" -> 200
"Test.Action3" -> 400
That is, a Dictionary<string, int>
.
I am interested in a LINQ solution but I can't manage to work around it.
I am trying to map each action to a KeyValuePair, but I don't know how to get each action's parent controller's Name property.
Upvotes: 4
Views: 952
Reputation: 110171
The main thing is the controller is still in scope in the lambda:
var result = controller.Actions.ToDictionary(
a => string.Format("{0}.{1}", controller.Name, a.Name),
a => a.HttpCache);
Upvotes: 6
Reputation: 16192
You can try this :
var dico = controller.Actions
.ToDictionary(a => $"{controller.Name}.{a.Name}",
a => a.HttpCache);
The first lambda expression target the key whereas the second target the value of the dictionary entry.
Upvotes: 1
Reputation: 14700
The LINQ approach is to project the Actions list, using the Select
method, into a dictionary. Since you're calling it on a Controller
instance, you have access to the Controller's Name
as well:
myController.Actions.ToDictionary(
/* Key selector - use the controller instance + action */
action => myController.Name + "." + action.Name,
/* Value selector - just the action */
action => action.HttpCache);
If you want to make one large dictionary from several controllers, you can use SelectMany
to project each Controller's items into a list of Controller+Action, then convert that list into a dictionary:
var namesAndValues =
controllers.SelectMany(controller =>
controller.Actions.Select(action =>
{
Name = controller.Name + "." + action.Name,
HttpCache = action.HttpCache
}));
var dict = namesAndValues.ToDictionary(nav => nav.Name, nav => nav.HttpCache);
Upvotes: 1
Reputation: 10280
Assuming that you have multiple controllers in a collection, not just the one controller
variable in your example code, and want to put all of their actions into a single dictionary, then you could do something like this:
var httpCaches = controllers.SelectMany(controller =>
controller.Actions.Select(action =>
new
{
Controller = controller,
Action = action
})
)
.ToDictionary(
item => item.Controller.Name + "." + item.Action.Name,
item => item.Action.HttpCache);
This would be for the case where you have your data set up like this:
var controllers = new[] {
new Controller()
{
Name = "Test1",
Actions = new Action[] {
new Action { Name = "Action1", HttpCache = 300 },
new Action { Name = "Action2", HttpCache = 200 },
new Action { Name = "Action3", HttpCache = 400 },
}
},
new Controller()
{
Name = "Test2",
Actions = new Action[] {
new Action { Name = "Action1", HttpCache = 300 },
new Action { Name = "Action2", HttpCache = 200 },
new Action { Name = "Action3", HttpCache = 400 },
}
},
};
Upvotes: 0