How do I get the value from a specific Key with Key Value Pair and VB.Net? - vb.net

Public _SecurityLevel As List(Of KeyValuePair(Of Integer, Integer))
Public Sub New()
_SecurityLevel.Add(New KeyValuePair(Of Integer, Integer)(1, 0))
_SecurityLevel.Add(New KeyValuePair(Of Integer, Integer)(2, 1))
_SecurityLevel.Add(New KeyValuePair(Of Integer, Integer)(3, 2))
_SecurityLevel.Add(New KeyValuePair(Of Integer, Integer)(4, 3))
_SecurityLevel.Add(New KeyValuePair(Of Integer, Integer)(5, 4))
_SecurityLevel.Add(New KeyValuePair(Of Integer, Integer)(6, 5))
End Sub
I want to get the value (3) when I specify the Key (4).
I don't want to iterate through the entire KVP until I find it.
Is this possible? If not what should I be using?

You can get it by using LINQ:
Dim theValue As Integer = _SecurityLevel.Find(Function(kvp) kvp.Key = 4).Value
But I would recommend to use a Dictionary instead, if no duplicate keys should occur.
Dim _SecurityLevel As New Dictionary(Of Integer, Integer)
_SecurityLevel.Add(1, 0)
_SecurityLevel.Add(2, 1)
_SecurityLevel.Add(3, 2)
_SecurityLevel.Add(4, 3)
_SecurityLevel.Add(5, 4)
_SecurityLevel.Add(6, 5)
Dim result As Integer
_SecurityLevel.TryGetValue(4, result)
Edit
As stated in the comments, FindIndex would be the better joice here, as Find will return a default KeyValuePair with key/value (0,0) if no entry is found in the list.
Something like the following would be more reliable:
Dim index As Integer = _SecurityLevel.FindIndex(Function(kvp) kvp.Key = 4)
If index > -1 Then
MsgBox(_SecurityLevel(index).Value)
Else
'Not found
End If

A Dictionary seems more appropriate for your application.
Public Class SomeClass
Public _SecurityLevel As New Dictionary(Of Integer, Integer)
Public Sub New()
_SecurityLevel.Add(1, 0)
_SecurityLevel.Add(2, 1)
_SecurityLevel.Add(3, 2)
_SecurityLevel.Add(4, 3)
_SecurityLevel.Add(5, 4)
_SecurityLevel.Add(6, 5)
End Sub
End Class
Private Sub OPCode()
Dim sc As New SomeClass
Dim v = sc._SecurityLevel(4)
Debug.Print(v.ToString)
'Prints 3
End Sub
It would be unusual to have a public field in a class.

Try this:
Dim valueFromKey As Integer = (From currentValue In _SecurityLevel.AsEnumerable
Where currentValue.Key = 4
Select currentValue.Value).FirstOrDefault

Related

Convert a List to a Dictionary with a unique numbered key

How can this code be accomplished using ToDictionary() instead of a For Each
Dim stringDict As Dictionary(Of String, String) = new Dictionary(Of Integer, String)
Dim stringList As List(Of String) = {"alpha", "beta", "gamma", "delta"}
For Each stringItem As String In stringList
stringDict.Add($"Entry{stringDict.Count+1}",stringItem)
Next
This is what I am trying to do:
Dim stringDict As Dictionary(Of String, String) = stringList.ToDictionary(Function(a) $"Entry{?}", Function(b) b)
I was hoping there might be a variable with the current row or index, or an incrementor
You can use the overload of Select that gives you the index:
Dim stringDict As Dictionary(Of String, String) = stringList.
Select(Function(s, index) (Key:=$"Entry{index + 1}", Value:=s)).
ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value)
However, i find your loop more readable. You should also set Option Strict to On, following should give you a compiler error:
Dim stringDict As Dictionary(Of String, String) = new Dictionary(Of Integer, String)
You can use Enumerable.Range (documentation) to create a range of numbers from 1 to the Count of your List and then Enumerable.ToDictionary (documentation) to convert that range to a Dictionary.
Example:
Dim stringList As New List(Of String) From {"alpha", "beta", "gamma", "delta"}
Dim stringDict = Enumerable.Range(1, stringList.Count).ToDictionary(Function(i) $"Entry{i}", Function(i) stringList.Item(i - 1))
Fiddle: https://dotnetfiddle.net/4xHp9g

Check for null value for value types in VB.NET

I have a KeyValuePair(Of TKey,TValue) and I want to check if it is null or not:
Dim dictionary = new Dictionary(Of Tkey,TValue)
Dim keyValuePair = dictionary.FirstOrDefault(Function(item) item.Key = *someValue*)
If keyValuePair isNot Nothing Then 'not valid because keyValuePair is a value type
....
End If
If keyValuePair <> Nothing Then 'not valid because operator <> does not defined for KeyValuePair(of TKey,TValue)
...
End If
How can I check if keyValuePair is null or not?
KeyValuePair(Of TKey, TValue) is a struct(Structure), it has default value which you can compare to.
Dim dictionary As New Dictionary(Of Integer, string)
Dim keyValuePair = dictionary.FirstOrDefault(Function(item) item.Key = 2)
Dim defaultValue AS KeyValuePair(Of Integer, string) = Nothing
If keyValuePair.Equals(defaultValue) Then
' Not found
Else
' Found
End If
Nothing represents default value of the corresponding type.
But because you are searching Dictionary for a key, you can use TryGetValue instead
Dim dictionary As New Dictionary(Of Integer, string)
Dim value As String
If dictionary.TryGetValue(2, value) Then
' Found
Else
' Not found
End If

Lempel-Ziv-Welch algorithm

Heys guys,
I'm trying to implement the Lempel-Ziv-Welch algorithm on byte level in VB.NET. Here is what the Code looks like so far:
Dim FileBytes As Byte() = {Convert.ToByte(12), Convert.ToByte(13), Convert.ToByte(12), Convert.ToByte(13), Convert.ToByte(12), Convert.ToByte(13)}
Dim bw As New BitWriter(New BinaryWriter(New FileStream(output, FileMode.Create)))
Dim ByteDictionary As New Dictionary(Of Byte(), Integer)
Dim DictionaryN As Integer = 1
Dim DictionaryMax As Integer = 4048
Dim outputs As New List(Of Integer)
Dim bts As New List(Of Byte)
For index As Integer = 0 To FileBytes.Length - 1
Dim currentbyte As Byte = FileBytes(index)
If ContainsByte(ByteDictionary, AddToList(bts, currentbyte).ToArray) Then
bts.Add(currentbyte)
Else
If bts.Count > 1 Then
ByteDictionary.Add(bts.ToArray, 255 + DictionaryN)
DictionaryN += 1
Else
ByteDictionary.Add(New Byte() {currentbyte}, currentbyte)
End If
Console.WriteLine(GetByteValue(ByteDictionary, bts.ToArray))
bts.Clear()
bts.Add(currentbyte)
End If
Next
End Sub
Public Function ContainsByte(ByVal dic As Dictionary(Of Byte(), Integer), ByVal bt As Byte()) As Boolean
Dim flag = True
For Each kp As KeyValuePair(Of Byte(), Integer) In dic
If ByteArrayEquals(kp.Key, bt) Then
Return True
End If
Next
Return False
End Function
Public Function AddToList(ByVal list As List(Of Byte), ByVal bt As Byte) As List(Of Byte)
Dim newlist = New List(Of Byte)(list)
newlist.Add(bt)
Return newlist
End Function
Public Function ByteArrayEquals(ByVal first As Byte(), ByVal second As Byte()) As Boolean
If first.Length = second.Length Then
Dim flag = True
For index As Integer = 0 To first.Length - 1
If first(index) <> second(index) Then
flag = False
End If
Next
Return flag
Else
Return False
End If
End Function
Public Function GetByteValue(ByVal dic As Dictionary(Of Byte(), Integer), ByVal bt As Byte()) As Integer
For Each kp As KeyValuePair(Of Byte(), Integer) In dic
If ByteArrayEquals(kp.Key, bt) Then
Return kp.Value
End If
Next
End Function
The idea behind my implementation is from https://www.cs.cf.ac.uk/Dave/Multimedia/node214.html . But somehow it doesn't work, it simply puts out the input bytes. What is wrong with it?
The main problem is these two lines:
If bts.Count > 1 Then
ByteDictionary.Add(bts.ToArray, 255 + DictionaryN)
In both lines here you're using bts where you should be using bts + currentByte, i.e. you want something like
Dim currentbyte As Byte = FileBytes(index)
Dim btsPlusCurrentByte As List(Of Byte) = AddToList(bts, currentbyte)
If ContainsByte(ByteDictionary, btsPlusCurrentByte.ToArray) Then
bts.Add(currentbyte)
Else
If btsPlusCurrentByte.Count > 1 Then
ByteDictionary.Add(btsPlusCurrentByte.ToArray, 255 + DictionaryN)
The other problem is that you'll complete the loop with data left in bts that you haven't output, so I think you'll need a block to do that afterwards. It may be safe to just do
Console.WriteLine(GetByteValue(ByteDictionary, bts.ToArray))
again after the Next but I haven't thought about that very carefully.
I also think you should be able to use .NET's own built-ins rather than your four helper functions.

VB dictionary contains value return key

I have a problem...
I am trying to put into a list of String dictionary keys values if condition of containsvalue is true:
But, this is not correct :(
here is a code:
Private listID As New List(Of String) ' declaration of list
Private dictionaryID As New Dictionary(Of String, Integer) ' declaration of dictionary
'put a keys and values to dictionary
dictionaryID.Add("first", 1)
dictionaryID.Add("second", 2)
dictionaryID.Add("first1", 1)
If dictionaryID.ContainsValue(1) Then ' if value of dictinary is 1
Dim pair As KeyValuePair(Of String, Integer)
listID.Clear()
For Each pair In dictionaryID
listID.Add(pair.Key)
Next
End If
And now, list must have two elements... -> "first" and "first1"
Can you help me?
Thank you very much!
You are looping through the whole dictionary and add all the elements to the list. You should put an if statement in the For Each or use a LINQ query like this:
If listID IsNot Nothing Then
listID.Clear()
End If
listID = (From kp As KeyValuePair(Of String, Integer) In dictionaryID
Where kp.Value = 1
Select kp.Key).ToList()
Using an if statement:
listID.Clear()
For Each pair As KeyValuePair(Of String, Integer) In dictionaryID
If pair.Value = 1 Then
listID.Add(pair.Key)
End If
Next
My VB.Net is a little rusty, but it looks like you were adding all of them, no matter if their value was 1 or not.
Private listID As New List(Of String) ' declaration of list
Private dictionaryID As New Dictionary(Of String, Integer) ' declaration of dictionary
'put a keys and values to dictionary
dictionaryID.Add("first", 1)
dictionaryID.Add("second", 2)
dictionaryID.Add("first1", 1)
If dictionaryID.ContainsValue(1) Then ' if value of dictinary is 1
Dim pair As KeyValuePair(Of String, Integer)
listID.Clear()
For Each pair In dictionaryID
If pair.Value = 1 Then
listID.Add(pair.Key)
End If
Next
End If

Filter a Dictionary to return a list

I know I can do this with a for loop cause that's how i'm doing it now. I was hoping for a more efficient way to accomplish the task.
I have a dictionary(Of Integer, Boolean)
or Of String, Boolean.
i want to get a list(of integer) or Of String from the dictionary where all the values are true(or false depending on what i need at the time)
and to generalize it or "black box" it, it could be any dictionary(of whatever, whatever)
and return a list(of whatever) where the value = whatever i'm looking for at the time.
string, string where value = "Closed"
in short: i want all list of all the keys who's value = some criteria
my current code:
Public Function FindInDict(Of tx, ty)(thedict As Dictionary(Of tx, ty), criteria As ty) As List(Of tx)
Dim tmpList As New List(Of tx)
For xloop As Integer = 0 To thedict.Count - 1
If CType(thedict(thedict.Keys(xloop)), ty).Equals(criteria) Then
tmpList.Add(thedict.Keys(xloop))
End If
Next
Return tmpList
End Function
You can do this easily with Linq:
Public Function FindInDict(Of tx, ty)(thedict As Dictionary(Of tx, ty), criteria As ty) As List(Of tx)
Return (From kvp In thedict
Where kvp.Value.Equals(criteria)
Select kvp.key).ToList()
End Function
Use LINQ, like so:
Dim tStorage As Dictionary(Of String, String) = New Dictionary(Of String, String)
Dim tKeys As List(Of String) = New List(Of String)
Dim tCriteria As List(Of String) = New List(Of String)
tStorage.Add("One", "Uno")
tStorage.Add("Two", "Dos")
tStorage.Add("Three", "Tres")
tStorage.Add("Four", "Quatro")
tCriteria.Add("Dos")
tCriteria.Add("Quatro")
tKeys = (From k In tStorage.Keys Where tCriteria.Contains(tStorage(k)) Select k).ToList
For Each tKey As String In tKeys
Console.WriteLine(tKey)
Next
Console.ReadKey()