how to convert value in a keypairs into list? - vb.net

Dim dict As New Dictionary(Of String, KeyValuePair(Of String, String))
dict.Add("key", New KeyValuePair(Of String, String)("value1","value2"))
I want to get value2 as a list.

Using LINQ Extensions:
' use KeyValuePair of dictionary, that gives 2 levels of KeyValuePairs
Dim list = dict.Select(function(kvp) kvp.Value.Value).ToList()
' Or use the Values part of Dictionary
Dim list = dict.Values.Select(function(v) v.Value).ToList()
' Adding some conditional and getting value1 instead:
Dim list = dict.Values.Where(function(k) k.Value = "value2").Select(function(v) v.Key).ToList()
For KeyValuePair x.Key is "value1" and x.Value is "value2"
Please note that this will get quite slow on big Dictionarys and there is probably better ways to handle this, but that requires more information about The actual use-case.

Related

how to check that a list contains another list item in VB.Net

I have two lists like this.
Dim List1 As IList(Of String) = New List(Of String)
Dim ListMatch As IList(Of String) = New List(Of String)
I need to figure out if List1 contains all items of ListMatch. How can i do this is VB.Net?
You can use Not SmallCollection.Except(LargeCollection).Any:
Dim containsAll = Not ListMatch.Except(List1).Any()
Documentation of Enumerable.Except:
This method returns those elements in first that do not appear in
second. It does not also return those elements in second that do not
appear in first.
Since Except is a set method, it doesn't take duplicates into account. So if you also want to know if List1 contains the same count of items of ListMatch you could use(less efficient):
Dim list1Lookup = List1.ToLookup(Function(str) str)
Dim listMatchLookup = ListMatch.ToLookup(Function(str) str)
Dim containsSameCount = listMatchLookup.
All(Function(x) list1Lookup(x.Key).Count() = x.Count())

How can i change the values in a dictionary that are inside another dictionary?

I've come here after hours of looking on the internet. Nothing comes close to what I am trying to achieve.
I have this:-
Private Portfolio_Client_List As New Dictionary(Of String, Dictionary(Of String, Double))
which I then add keys to like the following:-
Portfolio_Client_List.Add(str.Substring(6, 5).Trim, New Dictionary(Of String, Double))
then I add keys to the other dictionary like the below:-
For Each pair As KeyValuePair(Of String, Dictionary(Of String, Double)) In Portfolio_Client_List
pair.Value.Add("Office Collections", 0.00)
pair.Value.Add("Home Collections", 0.00)
Next
Now I want to update the values in the Office Collections and Home Collections keys values.
How can I do so? I thought it would be as simple as:-
For Each pair As KeyValuePair(Of String, Double) In Portfolio_Client_List("key")
pair.Value += Head_Office_Payments
Next
However it just gives me the readonly error. Is there any way to do this, or am I wasting my time?
No, KeyValuePairs are immutable structs, so you can't modify them, Value is readonly.
But this works (you want to add Head_Office_Payments to the old value):
Dim dict As Dictionary(Of String, Double) = Portfolio_Client_List("key")
For Each key As String In dict.Keys.ToList()
dict(key) += Head_Office_Payments
Next
Note that you need the dict.Keys.ToList(creates a new list) because you can't modify the collection while enumerating, setting the Value of a dictionary increases it's version number which invalidates the iterator. That's why i prefer this one-liner LINQ solution:
dict = dict.ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value + Head_Office_Payments)

What collection method should I use?

I have a text file and it looks like this
defabot:3215
defatank:2985
ludditus:29
compensate:355
moobot:805
maxi292003:63
doctorbarzhal:19
plaanz:4
manguuu:51
atntpc:19
immortalsofthemist:18
I'm loading this list when my application opens, splitting the name from number and populating a listview control with it. I want to maintain the list in memory for my entire project to use and manipulate.
I need the numbers associated with the name so when I search for the name I know how many points they have. What is the most efficient/easiest way to accomplish this?
Thank you.
Use Dictionary(Of String, Integer). Here is an example:
Dim dict As New Dictionary(Of String, Integer)
For Each s As String In IO.File.ReadAllLines("filename")
Dim a() As String = s.Split(":"c)
Dim userName As String = a(0)
Dim userPoints As Integer = Convert.ToInt32(a(1))
dict.Add(userName, userPoints)
Next
The most efficient way is to use a Dictionary(Of String, Int32):
Dim dict As Dictionary(Of String, Int32) = IO.File.ReadLines(path).
Select(Function(line) line.Split(":"c)).
ToDictionary(Function(split) split(0), Function(split) Int32.Parse(split(1)))
You get the value by it's key:
Dim ludditus As Int32 = dict("ludditus")

associative array like in php in vb.net

in PHP we know to make associative array using this code
$variable = array('0001'=>'value1', '0010'=>'value2');
and to print all keys and values using this code
foreach($variable as $key1 => $val1)
foreach($val1 as $key2 => $val2)
echo ("$key2 => $val2 <br />")
and the question is how to perform this in vb.net?
as i know to make associative array in vb.net using this :
Dim var As New Collection
var.Add("value1", "0001")
var.Add("value2", "0010")
how about to print value and key in vb.net like foreach in PHP? thanks
Although i'm not familiar with PHP (anymore), i assume that associative arrays are the equivalent of a HashTable or the more modern, strongly typed Dictionary:
Dim dict = New Dictionary(Of String, String)
dict.Add("value1", "0001")
dict.Add("value2", "0010")
Normally you would lookup keys:
Dim val2 = dict("value2") ' <-- 0010
But if you want to enumerate it (less efficient):
For Each kv As KeyValuePair(Of String, String) In dict
Console.WriteLine("Key:{0} Value:{1}",kv.Key, kv.Value)
Next
Dim row As Dictionary(Of String, Object)
Dim rows As Dictionary(Of String, Object)
row = New Dictionary(Of String, Object)
rows = New Dictionary(Of String, Object)
row.Add("a", 11)
row.Add("b", 22)
rows.Add("ab", row)

VB.Net Order a Dictionary(Of String, Integer) by value of the Integer

I have a dictionary of String, Integer so the key is the string and the value is the integer and i want to order the keys ascending by the value of the integer. How could I achieve this?
You could use LINQ to sort the Dictionary by value:
Dim dictionary = New Dictionary(Of String, Integer)()
dictionary.Add("A", 2)
dictionary.Add("B", 4)
dictionary.Add("C", 5)
dictionary.Add("D", 3)
dictionary.Add("E", 1)
Dim sorted = From pair In dictionary
Order By pair.Value
Dim sortedDictionary = sorted.ToDictionary(Function(p) p.Key, Function(p) p.Value)
Actually it does not modify the original Dictionary but creates a new Dictionary with the new order.
But: Apart from the feasability, a Dictionary is not an IList (as an Array or List<T>). It's purpose is to lookup a key very efficiently but not to loop all entries.
They are unordered, meaning that although you can retrieve the elements in some order with a foreach loop, that order has no special meaning, and it might change for no apparent reason.
First of all, a dictionary does not have an intrinsic order. It is for look-ups. However, you can turn the keys into their own ordered list.
Dim keyList as List(Of String) = (From tPair As KeyValuePair(Of String, Integer) _
In myDictionary Order By tPair.Value Ascending _
Select tPair.Key).ToList
I had to do something similar to this with custom objects. I think this should be close (but may not be exactly) what you're looking for:
Dim sortedL As List(Of KeyValuePair(Of String, Integer)) = yourDictionary.ToList
sortedL.Sort(Function(firstPair As KeyValuePair(Of String, Integer), nextPair As KeyValuePair(Of String, Integer)) CInt(firstPair.Value).CompareTo(CInt(nextPair.Value)))