I have the following code
IDictionary<string, IEnumerable<Control>>
I need to convert it to
IDictionary<string, IEnumerable<string>>
using ClientID as the new value.
Does anybody know how to do this in Linq instead iterating through the dictionary?
Thanks
Podge
Something like
IDictionary<string, IEnumerable<Control>> input = ...
IDictionary<string, IEnumerable<string>> output =
input.ToDictionary(item => item.Key,
item => item.Value.Select(control => control.ClientID));
Without having a compiler by hand, something like this should work...
dictOne
.ToDictionary(k=>k.Key, v=>v.Value.Select(c=>c.ClientID))
Related
I'm new to a programming with c#. How to extract IEnumarable key value pair from dictionary that has type <string, IEnumarable<KeyValuePair<string, string>>> to another dictionary<string, string>? Preferebly using linq. Thank you in advance.
Obviously KvpValues dictionary has some values in it. It's just a pseudo code for present what i have.
Trying to do something like that:
Dictionary<string, IEnumarable<KeyValuePair<string, string>>> KvpValues = new Dictionary<string, IEnumarable<KeyValuePair<string, string>>>();
Dictionary<string,string> values = KvpValues.Values.ForEach(k=>k.Key, v=>v.Value);
It seems like what you want to do is flatten the Values from the original Dictionary into a new Dictionary. Assuming there will be no key conflicts, your code is close, you just need to convert your IEnumerable<IEnumerable<KeyValuePair>> into a IEnumerable<KeyValuePair> which is what Enumerable.SelectMany does for you:
Dictionary<string,string> values = KvpValues.Values.SelectMany(kvs => kvs).ToDictionary(k => k.Key, v => v.Value);
I have a dictionary:
Dictionary<String, List<Foo>> test = new Dictionary<String, List<Foo>>();
I then populate this dictionary hence why I need the list so I can call Add(). My problem is the function needs to return:
Dictionary<String, IEnumerable<Foo>>
Is there any easy way to do this without doing the obvious and looping through my original dictionary and doing it manually?
return dictionary.ToDictionary(x => x.Key,x => x.Value.AsEnumerable())
It's more efficient and easier to use the List<Foo> to add things but add it to a Dictionary<String, IEnumerable<Foo>>. That's no problem since List<Foo> implements IEnumerable<Foo>, it's not even necessary to cast.
So something like this(pseudo code):
var test = new Dictionary<String, IEnumerable<Foo>>();
foreach(var x in something)
{
var list = new List<Foo>();
foreach(var y in x.SomeCollection)
list.Add(y.SomeProperty);
test.Add(x.KeyProperty, list); // works since List<T> is also an IEnumerable<T>
}
I tried this route as well, converting Dictionary<string, List<Foo>> to a ReadOnlyDictionary<string, IEnumerable<Foo>>. While I was trying to convert to a read-only dictionary, the whole purpose of converting a List to IEnumerable is to make a read only collection. The problem with the OP's approach is:
Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>();
errors["foo"] = new List<string>() { "You can't do this" };
Dictionary<string, IEnumerable<string>> readOnlyErrors = // convert errors...
readOnlyErrors["foo"] = new List<string>() { "I'm not actually read-only!" };
The appearance of IEnumerable<Foo> makes you think this is read only and safe, when in fact it is not. After reading the question LINQ Convert Dictionary to Lookup a Lookup object is more appropriate, because it allows you to:
Associate one key with multiple values
You cannot overwrite a key with a new value
// This results in a compiler error
lookUp["foo"] = new List<Foo>() { ... };
The "multiple values" are already defined as IEnumerable<T>
You can still use the same outer and inner loop algorithm to extract individual values:
ILookup<string, string> lookup = // Convert to lookup
foreach (IGrouping<string, string> grouping in lookup)
{
Console.WriteLine(grouping.Key + ":");
foreach (string item in grouping)
{
Console.WriteLine(" item: " + item);
}
}
Convert Dictionary<string, List<Foo>> to ILookup<string, Foo>
It's a quick two-liner:
Dictionary<string, List<Foo>> foos = // Create and populate 'foos'
ILookup<string, Foo> lookup = foos.SelectMany(item => item.Value, Tuple.Create)
.ToLookup(p => p.Item1.Key, p => p.Item2);
Now you can use the same two-step loop as you would have with a Dictionary<string, IEnumerable<Foo>>:
foreach (IGrouping<string, Foo> grouping in lookup)
{
string key = grouping.Key;
foreach (Foo foo in grouping)
{
// Do stuff with key and foo
}
}
Source: LINQ Convert Dictionary to Lookup
Converting to another Dictionary with an IEnumerable value is like trying to stuff a square peg into a round hole. The more appropriate, and safe way (from an object-oriented standpoint) is to convert your read/write Dictionary to a Lookup. This gives you the true intended safety of an object that is read-only (except for the Foo items, which might not be immutable).
I would go so far as to say that most times when a ReadOnlyDictionary is used, you could use ILookup and get the same functionality.
I have a schema generated from BizTalk. it doesn't understand the dictionary collection so it simply converts that to array of key value pair of string and string. Now when i am redirecting the request in a service i get
Dictionary<string, string> valuePairs
When i looked in to the reference.cs file i can see like this:
public bool ProcessMessage(string code, string template, Service.Proxy.ArrayOfKeyValueOfstringstringKeyValueOfstringstring[] valuePairs)
How can i convert this dictionary to array of key value of string string using linq? I know it's easy to do this using linq but any help will really be appreciated.
I have so far tried this but doesn't work:
ArrayOfKeyValueOfstringstringKeyValueOfstringstring[] array =
valuePairs.Select(pair => string.Format("{0},{1}", pair.Key, pair.Value))
.ToArray(KeyValuePair<string,string>);
try below , you may need to change the set properties of new object accordingly
ArrayOfKeyValueOfstringstringKeyValueOfstringstring[] array =
valuePairs.Select(pair =>
new ArrayOfKeyValueOfstringstringKeyValueOfstringstring(){
Key= pair.Key, Value= pair.Value}).ToArray();
What you can do is this, which converts your dictionary to the desired array:
KeyValuePair<string, string>[] kvps = valuePairs.ToArray();
I'm looking for the simplest way of converting a query string from an HTTP GET request into a Dictionary, and back again.
I figure it's easier to carry out various manipulations on the query once it is in dictionary form, but I seem to have a lot of code just to do the conversion. Any recommended ways?
HttpUtility.ParseQueryString() parses query string into a NameValueCollection object, converting the latter to an IDictionary<string, string> is a matter of a simple foreach. This, however, might be unnecessary since NameValueCollection has an indexer, so it behaves pretty much like a dictionary.
Here is how I usually do it
Dictionary<string, string> parameters = HttpContext.Current.Request.QueryString.Keys.Cast<string>()
.ToDictionary(k => k, v => HttpContext.Current.Request.QueryString[v]);
How about HttpUtility.ParseQueryString?
Just add a reference to System.Web.dll
Same as Sean, but with Linq (and a function you can copy and paste):
public static Dictionary<string, string> ParseQueryString(string queryString)
{
var nvc = HttpUtility.ParseQueryString(queryString);
return nvc.AllKeys.ToDictionary(k => k, k => nvc[k]);
}
Also, the question asked how to get it back into a query string:
public static string CreateQueryString(Dictionary<string, string> parameters)
{
return string.Join("&", parameters.Select(kvp =>
string.Format("{0}={1}", kvp.Key, HttpUtility.UrlEncode(kvp.Value))));
}
Just had to do this for a mono compatible solution
Regex.Matches(queryString, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value)
In ASP.NET Core, use ParseQuery.
var query = HttpContext.Request.QueryString.Value;
var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
I like the brevity of Jon Canning's answer, but in the interest of variety, here is another alternative to his answer, that would also work for restricted environments like Windows Phone 8, that lack the HttpUtility.ParseQueryString() utility:
public static Dictionary<string, string> ParseQueryString(String query)
{
Dictionary<String, String> queryDict = new Dictionary<string, string>();
foreach (String token in query.TrimStart(new char[] { '?' }).Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
{
string[] parts = token.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 2)
queryDict[parts[0].Trim()] = HttpUtility.UrlDecode(parts[1]).Trim();
else
queryDict[parts[0].Trim()] = "";
}
return queryDict;
}
Actually, a useful improvement to Canning's answer that take care of decoding url-encoded values (like in the above solution) is:
public static Dictionary<string, string> ParseQueryString2(String query)
{
return Regex.Matches(query, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => HttpUtility.UrlDecode( x.Groups[3].Value ));
}
One liner without HttpUtility
var dictionary = query.Replace("?", "").Split('&').ToDictionary(x => x.Split('=')[0], x => x.Split('=')[1]);
Yet another way to do it:
NameValueCollection nvcData = HttpUtility.ParseQueryString(queryString);
Dictionary<string, string> dictData = new Dictionary<string, string>(nvcData.Count);
foreach (string key in nvcData.AllKeys)
{
dictData.Add(key, nvcData.Get(key));
}
Most simple:
Dictionary<string, string> parameters = new Dictionary<string, string>();
for (int i = 0; i < context.Request.QueryString.Count; i++)
{
parameters.Add(context.Request.QueryString.GetKey(i), context.Request.QueryString[i]);
}
I stumbled across this post whilst looking for the same solution for an Azure WebJob, hopefully this helps others doing the same.
If you are coding an Azure WebJob you use the GetQueryParameterDictionary() extension method.
var queryParameterDictionary = request.GetQueryParameterDictionary();
where request is of type HttpRequest and queryParameterDictionary is now of type IDictionary<string, string>
You can just get it by decorating the parameter with the FromQueryAttribute
public void Action([FromQuery] Dictionary<string, string> queries)
{
...
}
P.S. If you want to get multiple values for each key you can change the Dictionary to Dictionary<string, List<string>>
Instead of converting HttpContext.Request.QueryString to Dictionary<>, try using
HttpContext.Request.Query
which already is a Dictionary<string, StringValues>
AspNet Core now automatically includes HttpRequest.Query which can be used similar to a dictionary with key accessors.
However if you needed to cast it for logging or other purposes, you can pull out that logic into an extension method like this:
public static class HttpRequestExtensions
{
public static Dictionary<string, string> ToDictionary(this IQueryCollection query)
{
return query.Keys.ToDictionary(k => k, v => (string)query[v]);
}
}
Then, you can consume it on your httpRequest like this:
var params = httpRequest.Query.ToDictionary()
Further Reading
How to parse a query string into a NameValueCollection in .NET
Convert query string to key-value pair in .Net
Is it possible to get Dictionary from query string?
Dictionary<string, string> optionDictionary = new Dictionary<string, string>();
optionDictionary = ....;
SortedDictionary<string, string> optionsSorted;
if(sorting)
{
optionsSorted = new SortedDictionary<string, string>(optionDictionary );
// Convert SortedDictionary into Dictionary
}
return optionDictionary ;
You can pass in your optionsSorted<TKey,TValue> dictionary as a parameter to an instance of a new Dictionary<TKey,TValue>, Like so:
var dictionary = new Dictionary<type1,type2>(optionsSorted);
Try the following
var dictionary = optionsSorted.ToDictionary(x => x.Key, x=> x.Value);
It is not entirely clear to me what you are trying to accomplish. I am assuming that you have a function that returns a Dictionary and you want it to be a sorted dictionary when sorting is true.
If that is true, then you need a return type that can be a Dictionary or a SortedDictionary.
If you want a single function doing that, I would use IDictionay as return type of the method.
Just use the ToDictionary method.