I have this
foreach (KeyValuePair<string, Object> tempData in tempList.ToDictionary(x => x.Key, y => y.Value))
{
tempData["fahrzeugA"] = "s";
}
But using tempData["fahrzeugA"] = "s"; will not work.
I get:
Cannot apply indexing with [] to an expression of type
'System.Collections.Generic.KeyValuePair'
What is the correct syntax if I have an existing key fahrzeugA, which I want to alter ?
You can apply this :
var tempList = new List<Test>();
var dic = tempList.ToDictionary(x => x.Key, y => y.Value);
foreach (var tempData in dic)
{
dic[tempData.Key] = "s";
}
You can't change the key value pair since it is an immutable struct. The only way to change it is to create a new instance. That instance would live independent from the dictionary.
If you want to change the value in the dictionary, use the indexer property on the dictionary to change the value.
And even then, the dictionary will go out of scope immediately, so there is no use setting it. It won't affect the original list.
Check KeyValuePair.Value Property. It's readonly and can't be altered.
ToDictionary creates a new object. You can't alter original object by accessing its elements' value.
You have to remove this specific item from original list and add new item of the same key back.
var removeIndex = tempList.FindIndex(kp => kp.Key == "fahrzeugA");
tempList.RemoveAt(removeIndex);
tempList.Add(new KeyValuePair<string, string>("fahrzeugA", "s"));
If there are multiple "fahrzeugA" items (it's valid in list but not valid in dictionary), use RemoveAll instead.
If your tempList is List<KeyValuePair<string, Object>> type:
for (var i = 0; i < tempList.Count; ++i) {
if (tempList[i].Key == "fahrzeugA") {
tempList[i] = new KeyValuePair<string, object> ("fahrzeugA", "s"); // KeyValuePair<string, object> might be changed with your own type if you use something else.
break; // If you want to modify only first KeyValuePair.
}
}
If you have successfully turned your tempList into a dictionary, there can only be one "fahrzeugA" (since all keys must be unique), so looping makes no sense.
You should be able to just say:
var dictionary = tempList.ToDictionary(x => x.Key, y => y.Value);
dictionary["fahrzeugA"] = "s";
If you don't want to create the dictionary in the first place, you could do this:
var matchingKeyValuePair = tempList.SingleOrDefault(x => x.Key == "fahrzeugA");
if (matchingKeyValuePair != null) matchingKeyValuePair.Value = "s";
If you are using a list of .NET KeyValuePair<TKey, TValue>, which is an immutable struct, you can replace the value with a new KeyValuePair, like this:
var matchingIndex = tempList.FindIndex(x => x.Key == "fahrzeugA");
if (matchingIndex >= 0)
tempList[matchingIndex] = new KeyValuePair<string, string>("fahrzeugA", "s");
Note, this assumes that you only have one item with a key of "fahrzeugA".
Related
I have a list of KeyValuePair which its values are list too such as
List<KeyValuePair<string, List<string>>> ListX = new List<KeyValuePair<string,List<string>>>();
ListX.Add(new KeyValuePair<string,List<string>>("a",list1));
ListX.Add(new KeyValuePair<string,List<string>>("b",list1));
ListX.Add(new KeyValuePair<string,List<string>>("a",list1));`
I want the keys of each KeyValuePair in the list to be not duplicated, only the keys, can I use Distinct in this list?
for example I want the third item in the list that has "a" key to be deleted because it's duplicated.
Though it is possible to work around with your current List to make it having Distinct keys, the simplest solution which I think fit for your case is to use Dictionary<string,List<string>>
It does just exactly what you need:
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
dict.Add("a", new List<string>());
dict.Add("b", new List<string>());
dict.Add("a", new List<string>()); //will throw an error
Image:
If you need to check if a Key is already exist when you want to add a <Key,Value> to a your dictionary, simply check by ContainsKey:
if (dict.ContainsKey(key)) //the key exists
var dictionaryX = ListX
.GroupBy(x => x.Key, (x, ys) => ys.First())
.ToDictionary(x => x.Key, x => x.Value);
I'm not sure if this is what you were looking for, but it's a query that will convert a ListX into a dictionary by only taking the first value for each duplicate key.
You can use class Dictionary<TKey, TValue> which inherits from IEnumerable<KeyValuePair<TKey, TValue>>. It is a collection of KeyValuePairs which allows only unique keys.
U can use
Dictionary<TKey, TValue>
where Tkey and Tvalue are generic datatypes.
For example they can be int, string,another dictionary etc.
ExampleDictionary<int , string>, Dictionary<int , List<employee>> etc.
In all these cases the key is the distinct part ie, same key cannot be inserted again.
U can check if key exists using Distinct so that no exception occurs even if u try to add same key
However Distinct prevents only same key value pairs .
To prevent same key being added use Enumerable.GroupBy
ListItems.Select(item =>
{
long value;
bool parseSuccess = long.TryParse(item.Key, out value);
return new { Key = value, parseSuccess, item.Value };
})
.Where(parsed => parsed.parseSuccess)
.GroupBy(o => o.Key)
.ToDictionary(e => e.Key, e => e.First().Value)
List<Dictionary<int, List<int>>> list = new List<Dictionary<int, List<int>>>(); //List with a dictinary that contains a list
int key = Convert.ToInt32(Console.ReadLine()); // Key that you want to check if it exist in the dictinary
int temp_counter = 0;
foreach(Dictionary<Int32,List<int>> dict in list)
{
if(dict.ContainsKey(key))
temp_counter+=temp_counter;
}
if (temp_counter == 0) // key not present in dictinary then add a to the list a dictinary object that contains your list
{
Dictionary<int,List<int>> a = new Dictionary<int,List<int>>();
a.Add(key,new List<int>()); // will contain your list
list.Add(a);
}
Check if this works
List<KeyValuePair<String, String> myList = new List<KeyValuePair<String, String>>();
myList.Add(new KeyValuePair<String, SelectList>("theKey", "FIND THIS!"));
How can I retrieve "FIND THIS!" from myList knowing only theKey? This attempt is not working.
String find = myList.Where(m => m.Key == "theKey");
Coming from other languages, I've always had the possibility to search in big associative arrays and retrieve values like this: array[key] = value;
How can I do this in C#?
Instead of List<KeyValuePair>, use Dictionary<string, SelectList> and then you can access it like :
array[key] = value;
You can use Dictionary like:
Dictionary<String, SelectList> dictionary= new Dictionary<String, SelectList>();
dictionary.Add("theKey", "FIND THIS!");
Console.WriteLine(dictionary["theKey"]);
You are probably looking for the Dictionary<TKey, TValue>:
Dictionary<string, string> myDict = new Dictionary<string, string>();
myDict.Add("theKey", "FIND THIS!");
now you can find the value via the key:
string value = myDict["theKey"];
You can change the value in this way:
myDict["theKey"] = "new value"; // works even if the key doesn't exist, then it will be added
Note that the keys must be unique.
How about Dictionary ?
IDictionary<String, String> foo = new Dictionary<String, String>();
foo.Add("hello","world");
now you can use []
foo["Hello"];
however with C#
string value;
if(foo.TryGetValue("Hello" , out value)){
// now you have value
}
is much more preferable and safer.
As mentioned in other answers you should use a Dictionary for this.
However, the reason your line String find = myList.Where(m => m.Key == "theKey"); is not working is that myList.Where(m => m.Key == "theKey"); will return a KeyValuePair. If you just want the value you could try:
String find = myList.Where(m => m.Key == "theKey").Single().Value;
or if you need to check for nulls then maybe:
var findKeyValue = myList.Where(m => m.Key == "theKey").SingleOrDefault();
if(findKeyValue != null)
{
var find = findKeyValue.Value;
}
You can also use the following snippet (in which case you'll either have the value or null)
var find = myList.Where(m => m.Key == "theKey").Select(kvp => kvp.Value).SingleOrDefault();
I have below code in c# 4.0.
//Dictionary object with Key as string and Value as List of Component type object
Dictionary<String, List<Component>> dic = new Dictionary<String, List<Component>>();
//Here I am trying to do the loping for List<Component>
foreach (List<Component> lstComp in dic.Values.ToList())
{
// Below I am trying to get first component from the lstComp object.
// Can we achieve same thing using LINQ?
// Which one will give more performance as well as good object handling?
Component depCountry = lstComp[0].ComponentValue("Dep");
}
Try:
var firstElement = lstComp.First();
You can also use FirstOrDefault() just in case lstComp does not contain any items.
http://msdn.microsoft.com/en-gb/library/bb340482(v=vs.100).aspx
Edit:
To get the Component Value:
var firstElement = lstComp.First().ComponentValue("Dep");
This would assume there is an element in lstComp. An alternative and safer way would be...
var firstOrDefault = lstComp.FirstOrDefault();
if (firstOrDefault != null)
{
var firstComponentValue = firstOrDefault.ComponentValue("Dep");
}
[0] or .First() will give you the same performance whatever happens.
But your Dictionary could contains IEnumerable<Component> instead of List<Component>, and then you cant use the [] operator. That is where the difference is huge.
So for your example, it doesn't really matters, but for this code, you have no choice to use First():
var dic = new Dictionary<String, IEnumerable<Component>>();
foreach (var components in dic.Values)
{
// you can't use [0] because components is an IEnumerable<Component>
var firstComponent = components.First(); // be aware that it will throw an exception if components is empty.
var depCountry = firstComponent.ComponentValue("Dep");
}
You also can use this:
var firstOrDefault = lstComp.FirstOrDefault();
if(firstOrDefault != null)
{
//doSmth
}
for the linq expression you can use like this :
List<int> list = new List<int>() {1,2,3 };
var result = (from l in list
select l).FirstOrDefault();
for the lambda expression you can use like this
List list = new List() { 1, 2, 3 };
int x = list.FirstOrDefault();
You can do
Component depCountry = lstComp
.Select(x => x.ComponentValue("Dep"))
.FirstOrDefault();
Alternatively if you are wanting this for the entire dictionary of values, you can even tie it back to the key
var newDictionary = dic.Select(x => new
{
Key = x.Key,
Value = x.Value.Select( y =>
{
depCountry = y.ComponentValue("Dep")
}).FirstOrDefault()
}
.Where(x => x.Value != null)
.ToDictionary(x => x.Key, x => x.Value());
This will give you a new dictionary. You can access the values
var myTest = newDictionary[key1].depCountry
Try this to get all the list at first, then your desired element (say the First in your case):
var desiredElementCompoundValueList = new List<YourType>();
dic.Values.ToList().ForEach( elem =>
{
desiredElementCompoundValue.Add(elem.ComponentValue("Dep"));
});
var x = desiredElementCompoundValueList.FirstOrDefault();
To get directly the first element value without a lot of foreach iteration and variable assignment:
var desiredCompoundValue = dic.Values.ToList().Select( elem => elem.CompoundValue("Dep")).FirstOrDefault();
See the difference between the two approaches: in the first one you get the list through a ForEach, then your element. In the second you can get your value in a straight way.
Same result, different computation ;)
There are a bunch of such methods:
.First .FirstOrDefault .Single .SingleOrDefault
Choose which suits you best.
var firstObjectsOfValues = (from d in dic select d.Value[0].ComponentValue("Dep"));
I would to it like this:
//Dictionary object with Key as string and Value as List of Component type object
Dictionary<String, List<Component>> dic = new Dictionary<String, List<Component>>();
//from each element of the dictionary select first component if any
IEnumerable<Component> components = dic.Where(kvp => kvp.Value.Any()).Select(kvp => (kvp.Value.First() as Component).ComponentValue("Dep"));
but only if it is sure that list contains only objects of Component class or children
I have a Dictionary<string, string>.
I need to look within that dictionary to see if a value exists based on input from somewhere else and if it exists remove it.
ContainsValue just says true/false and not the index or key of that item.
Help!
Thanks
EDIT: Just found this - what do you think?
var key = (from k in dic where string.Compare(k.Value, "two", true) ==
0 select k.Key).FirstOrDefault();
EDIT 2: I also just knocked this up which might work
foreach (KeyValuePair<string, string> kvp in myDic)
{
if (myList.Any(x => x.Id == kvp.Value))
myDic.Remove(kvp.Key);
}
Are you trying to remove a single value or all matching values?
If you are trying to remove a single value, how do you define the value you wish to remove?
The reason you don't get a key back when querying on values is because the dictionary could contain multiple keys paired with the specified value.
If you wish to remove all matching instances of the same value, you can do this:
foreach(var item in dic.Where(kvp => kvp.Value == value).ToList())
{
dic.Remove(item.Key);
}
And if you wish to remove the first matching instance, you can query to find the first item and just remove that:
var item = dic.First(kvp => kvp.Value == value);
dic.Remove(item.Key);
Note: The ToList() call is necessary to copy the values to a new collection. If the call is not made, the loop will be modifying the collection it is iterating over, causing an exception to be thrown on the next attempt to iterate after the first value is removed.
Dictionary<string, string> source
//
//functional programming - do not modify state - only create new state
Dictionary<string, string> result = source
.Where(kvp => string.Compare(kvp.Value, "two", true) != 0)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
//
// or you could modify state
List<string> keys = source
.Where(kvp => string.Compare(kvp.Value, "two", true) == 0)
.Select(kvp => kvp.Key)
.ToList();
foreach(string theKey in keys)
{
source.Remove(theKey);
}
Loop through the dictionary to find the index and then remove it.
Here is a method you can use:
public static void RemoveAllByValue<K, V>(this Dictionary<K, V> dictionary, V value)
{
foreach (var key in dictionary.Where(
kvp => EqualityComparer<V>.Default.Equals(kvp.Value, value)).
Select(x => x.Key).ToArray())
dictionary.Remove(key);
}
You can use the following as extension method
public static void RemoveByValue<T,T1>(this Dictionary<T,T1> src , T1 Value)
{
foreach (var item in src.Where(kvp => kvp.Value.Equals( Value)).ToList())
{
src.Remove(item.Key);
}
}
In my case I use this
var key=dict.FirstOrDefault(m => m.Value == s).Key;
dict.Remove(key);
Is there a built-in function for converting a string array into a dictionary of strings or do you need to do a loop here?
Assuming you're using .NET 3.5, you can turn any sequence (i.e. IEnumerable<T>) into a dictionary:
var dictionary = sequence.ToDictionary(item => item.Key,
item => item.Value)
where Key and Value are the appropriate properties you want to act as the key and value. You can specify just one projection which is used for the key, if the item itself is the value you want.
So for example, if you wanted to map the upper case version of each string to the original, you could use:
var dictionary = strings.ToDictionary(x => x.ToUpper());
In your case, what do you want the keys and values to be?
If you actually just want a set (which you can check to see if it contains a particular string, for example), you can use:
var words = new HashSet<string>(listOfStrings);
You can use LINQ to do this, but the question that Andrew asks should be answered first (what are your keys and values):
using System.Linq;
string[] myArray = new[] { "A", "B", "C" };
myArray.ToDictionary(key => key, value => value);
The result is a dictionary like this:
A -> A
B -> B
C -> C
IMO, When we say an Array we are talking about a list of values that we can get a value with calling its index (value => array[index]), So a correct dictionary is a dictionary with a key of index.
And with thanks to #John Skeet, the proper way to achieve that is:
var dictionary = array
.Select((v, i) => new {Key = i, Value = v})
.ToDictionary(o => o.Key, o => o.Value);
Another way is to use an extension method like this:
public static Dictionary<int, T> ToDictionary<T>(this IEnumerable<T> array)
{
return array
.Select((v, i) => new {Key = i, Value = v})
.ToDictionary(o => o.Key, o => o.Value);
}
If you need a dictionary without values, you might need a HashSet:
var hashset = new HashSet<string>(stringsArray);
What do you mean?
A dictionary is a hash, where keys map to values.
What are your keys and what are your values?
foreach(var entry in myStringArray)
myDictionary.Add(????, entry);
I'll assume that the question has to do with arrays where the keys and values alternate. I ran into this problem when trying to convert redis protocol to a dictionary.
private Dictionary<T, T> ListToDictionary<T>(IEnumerable<T> a)
{
var keys = a.Where((s, i) => i % 2 == 0);
var values = a.Where((s, i) => i % 2 == 1);
return keys
.Zip(values, (k, v) => new KeyValuePair<T, T>(k, v))
.ToDictionary(kv => kv.Key, kv => kv.Value);
}
Dictionary<int, string> dictionaryTest = new Dictionary<int, string>();
for (int i = 0; i < testArray.Length; i++)
{
dictionaryTest.Add(i, testArray[i]);
}
foreach (KeyValuePair<int, string> item in dictionaryTest)
{
Console.WriteLine("Array Position {0} and Position Value {1}",item.Key,item.Value.ToString());
}
The Question is not very clear, but Yes you can convert a string to Dictionary provided the string is delimited with some characters to support Dictionary<Key,Value> pair
So if a string is like a=first;b=second;c=third;d=fourth you can split it first based on ; then on = to create a Dictionary<string,string> the below extension method does the same
public static Dictionary<string, string> ToDictionary(this string stringData, char propertyDelimiter = ';', char keyValueDelimiter = '=')
{
Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
Array.ForEach<string>(stringData.Split(propertyDelimiter), s =>
{
if(s != null && s.Length != 0)
keyValuePairs.Add(s.Split(keyValueDelimiter)[0], s.Split(keyValueDelimiter)[1]);
});
return keyValuePairs;
}
and can use it like
var myDictionary = "a=first;b=second;c=third;d=fourth".ToDictionary();
since the default parameter is ; & = for the extension method.
You can create a dictionary from an IEnumerable<T>, including an array, via:
var dictionary = myEnumerable.ToDictionary(element => element.Key,
element => element.Value)
where Key and Value are the key and value you want to store in each dictionary element. Available in .NET Framework 3.5+/.NET Core 1.0+/.NET 5.0+. Official documentation.
If you want the dictionary values to be the elements from the original enumerable:
var dictionary = myEnumerable.ToDictionary(element => element.Key)
If you only need high-performance set operations, you may be able to use:
var words = new HashSet<string>(listOfStrings);
In simple terms, the HashSet class can be thought of as a Dictionary<TKey,TValue> collection without values. Official documentation.
(Note that a 'sequence' in an entirely unrelated object.
Originally submitted an existing answer edit but it was rejected by the author so posting separately, including with links to the official Microsoft documentation.)