Get dictionary key by list value - c#

I'll take inspiration from this previous question. I have a dictionary with lists inside, and I want to get the key by a value inside one of those.
Dictionary<string, List<string>> myDict = new Dictionary<string, List<string>>
{
{"1", new List<string>{"1a", "1b"} },
{"2", new List<string>{"2a", "2b"} },
{"3", new List<string>{"3a", "3b"} },
};
I'm confident that all values inside are unique.
I want something like this:
getByValueKey(string value);
getByValueKey("2a") must be return "2".

if you want to use linq, you could write:
var result = myDict.FirstOrDefault(p => p.Value.Contains(stringTofind)).Key;

I like Frenchy's answer, but if you're looking for a non-linqy solution, then:
Dictionary<string, List<string>> myDict = new Dictionary<string, List<string>>
{
{"1", new List<string>{"1a", "1b"} },
{"2", new List<string>{"2a", "2b"} },
{"3", new List<string>{"3a", "3b"} },
};
string stringToFind = "2a";
string matchingKey = null;
foreach(KeyValuePair<string, List<string>> kvp in myDict)
{
if (kvp.Value.Contains(stringToFind))
{
matchingKey = kvp.Key;
break;
}
}
if (matchingKey != null)
{
System.Console.WriteLine("Matching Key: " + matchingKey);
}
else
{
System.Console.WriteLine("No match found.");
}

Related

dictionary to json with key names

I have a dictionary Dictionary<int, string> of ints and strings, where ints are ids and strings are usernames, and when I convert it to JSON using Json.NET I get something like the following:
{"3":"jack","2":"john"}
I convert it like so:
Dictionary<int, string> dictFriends = new Dictionary<int, string>();
foreach (var id in resultList)
{
var user = db.Users.Find(id);
string friend = user.Username;
dictFriends.Add(id, friend);
}
string json = JsonConvert.SerializeObject(dictFriends);
But I am hoping to get something like so:
[
{ "id": "3", "user": "jack"},
{ "id": "2", "user": "john"},
]
Is it possible?
As far as I know you'd have to transform the dictionary into something JSON.NET would recognise as being an IEnumerable:
// YOUR DICTIONARY
var dictFriends = new Dictionary<int, string>() {
{1,"Jack"},
{2,"John"},
{3,"Jeff"}
};
// TRANSFORM INTO IENUMERABLE
var transformed = from key in dictFriends.Keys
select new { id = key, user = dictFriends[key] };
// SERIALIZE
var json = JsonConvert.SerializeObject(transformed);
Output:
[
{"id":1, "user":"Jack"},
{"id":2, "user":"John"},
{"id":3, "user":"Jeff"}
]
You're trying to use a Dictionary as an Array/List, writing to an existing key will overwrite it. Also your current key type is int therefore you would have JSON output such as
{1: "jack", 2: "john"}
Instead set your object type to List<Dictionary<string, Object>>
List<Dictionary<string, object>> friends = new List<Dictionary<string, Object>>();
foreach (var id in resultList)
{
var user = db.Users.Find(id);
string friend = user.Username;
Dictionary<string, object> dictFriend = new Dictionary<string, Object>();
dictFriend.Add("id", id);
dictFriend.Add("name" , friend);
friends.Add(dictFriend);
}
string json = JsonConvert.SerializeObject(friends);
You could use the DataContractJsonSerializer: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer(v=vs.110).aspx
The below will produce output in the form you're after; only instead of id and user your fields would be named key and value. The reason being those are the property names on the dictionary.
If you needed to change those names also (i.e. it's not just the structure you're interested in), you'd need to override the dictionary with a custom class, where you could add attributes such as [JsonProperty(PropertyName = "User")] to the properties to change how they're parsed... See http://www.newtonsoft.com/json/help/html/SerializationAttributes.htm for more.
Dictionary<int, string> dictFriends = new Dictionary<int, string>();
dictFriends.Add(1, "Alice");
dictFriends.Add(2, "Bob");
string jsonString;
using (MemoryStream ms = new MemoryStream()) {
//NB: DataContractJsonSerializer is in assembly System.Runtime.Serialization.dll - and others; http://stackoverflow.com/a/2682197/361842
DataContractJsonSerializer dcjs = new DataContractJsonSerializer(dictFriends.GetType());
dcjs.WriteObject(ms, dictFriends);
ms.Position = 0;
using(StreamReader sr = new StreamReader(ms)) {
jsonString = sr.ReadToEnd();
}
}
Debug.WriteLine(jsonString);
Sample output:
[{"Key":1,"Value":"Alice"},{"Key":2,"Value":"Bob"}]

How to Iterate Through GroupBy - Getting Duplicate Key Error

I can't figure out how to do this right. I want to be able to iterate this dictionary because it's for my unit test and so each pair for me is important to have in here
var invalidPageNumberAndSize = new Dictionary<string, string>
{
{"0", ""},
{"", "0"},
{"abc", ""},
{"", "abc"}
}.GroupBy(p => p.Key);
foreach (var invalidPagingCombination in invalidPageNumberAndSize)
{
Console.WriteLine(invalidPagingCombination.Key + " " + invalidPagingCombination);
}
Use a collection of KeyValuePair instead of dictionary:
var invalidPageNumberAndSize = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("0", ""),
new KeyValuePair<string, string>("", "0"),
new KeyValuePair<string, string>("abc", ""),
new KeyValuePair<string, string>("", "abc")
}.GroupBy(p => p.Key);
You are entering two keys in your dictionary that are empty:
{"", "0"},
and
{"", "abc"}
change this to
{"foo", "abc"}
and the error will go away. A dictionary can only have 1 instance of each key. You could also use a List of Tuples if you needed to:
var list = new List<Tuple<string, string>>();
list.Add(new Tuple<string, string>("", "apple"));
list.Add(new Tuple<string, string>("", "zebra"));

How can I populate a NameValueCollection via a parameter in a shared method?

I have a code segment:
var requestMock = new Mock<HttpRequestBase>();
var queryString = new NameValueCollection();
queryString["abc"] = "123";
queryString["qwe"] = "456";
queryString["yui"] = "678";
...
requestMock.SetupGet(rqst => rqst.QueryString).Returns(queryString);
Now, I would like to have the above segment written as a method:
var requestMock = GetRequestMock(???);
I intend to send the query string key/values which can be anything.
And the count of k/v pairs also can be anything.
public Mock<HttpRequestBase> GetRequestMock(???)
{
var requestMock = new Mock<HttpRequestBase>();
....
requestMock.SetupGet(rqst => rqst.QueryString).Returns(queryString);
return requestMock;
}
What would be the best way to do this eficiently and simply?
One way would be to use a Dictionary:
public Mock<HttpRequestBase> GetRequestMock(Dictionary<string, object> queryParms)
{
var queryString = new NameValueCollection();
foreach (KeyValuePair<string, object> kvp in queryParms)
{
queryString[kvp.Key] = Convert.ToString(kvp.Value);
}
...
}
and then you can call it like this:
GetRequestMock(new Dictionary<string, object> { { "abc", "123" }, { "qwe", "456" } } );

Creating the IEnumerable<KeyValuePair<string, string>> Objects with C#?

For testing purposes, I need to create an IEnumerable<KeyValuePair<string, string>> object with the following sample key value pairs:
Key = Name | Value : John
Key = City | Value : NY
What is the easiest approach to do this?
any of:
values = new Dictionary<string,string> { {"Name", "John"}, {"City", "NY"} };
or
values = new [] {
new KeyValuePair<string,string>("Name","John"),
new KeyValuePair<string,string>("City","NY")
};
or:
values = (new[] {
new {Key = "Name", Value = "John"},
new {Key = "City", Value = "NY"}
}).ToDictionary(x => x.Key, x => x.Value);
Dictionary<string, string> implements IEnumerable<KeyValuePair<string,string>>.
var List = new List<KeyValuePair<String, String>> {
new KeyValuePair<String, String>("Name", "John"),
new KeyValuePair<String, String>("City" , "NY")
};
Dictionary<string,string> testDict = new Dictionary<string,string>(2);
testDict.Add("Name","John");
testDict.Add("City","NY");
Is that what you mean, or is there more to it?
You can simply assign a Dictionary<K, V> to IEnumerable<KeyValuePair<K, V>>
IEnumerable<KeyValuePair<string, string>> kvp = new Dictionary<string, string>();
If that does not work you can try -
IDictionary<string, string> dictionary = new Dictionary<string, string>();
IEnumerable<KeyValuePair<string, string>> kvp = dictionary.Select((pair) => pair);

LINQ: Get the data from the Dictionary in c#

I have a Dictionary> in c#:
Dictionary<string, List<string>> l_dictRawData =
new Dictionary<string, List<string>> {
{ "TamilNadu", new List<string>{ "Chennai", "Madurai" }},
{ "Andhra", new List<string>{"Hyderabad", "Secundarabad" }},
{ "Karnataka", new List<string>{"mysore", "Bangalore" }}
};
Then I have the InputList:
List<string> l_lstInput = new List<string> { "Hyderabad", "Secundarabad" };
The result will be the (i.e) if the dictionary l_dictRawData contains both "Hyderabad" and "Secundarabad" ,then select the key value:
string l_strOutPut = "Andhra";
Here is my code :
var Query = from l_strData in l_dictRawData
from l_strItem in l_lstInput
where l_strData .Value.Contains(l_strItem )
select new { CityName = l_strItem,
StateName = l_strData.Key
};
How can i get the ouput using LINQ in c#
Do you know that the list's data will be in the same order as the dictionary value's order? If so:
var result = l_dictRawData.Where(pair => pair.Value.SequenceEqual(l_lstInput))
.Select(pair => pair.Key)
.FirstOrDefault();

Categories