NewtonSoft Json Deserialize two dimensional array - arrays

I have the following JSON.
[["NAME","S0101_C01_008EA","S0101_C01_031M","state","county"],
["Alcona County, Michigan",null,"1.1","26","001"],
["Alger County, Michigan",null,"1.7","26","003"],
["Allegan County, Michigan",null,"0.2","26","005"],
["Alpena County, Michigan",null,"0.9","26","007"],
["Antrim County, Michigan",null,"0.9","26","009"],
["Arenac County, Michigan",null,"0.8","26","011"]]
I'm trying to deserialize it into an array of objects. I'm not sure why I'm having such a hard time.
I can get the info I need using .
Dim PopulationByState As List(Of JArray) = JsonConvert.DeserializeObject(Of List(Of JArray))(response)
Dim lst As New List(Of String) 'create a new list to hold the strings
For Each t As JToken In PopulationByState
For Each i In t.Children()
ListBox1.Items.Add(i)
Next
Next

You may deserialize it to a List(Of List(Of Object)):
Dim PopulationByState As List(Of List(Of Object)) = _
JsonConvert.DeserializeObject(Of List(Of List(Of Object)))(response)
Dim state As List(Of Object)
For Each state In PopulationByState.Skip(1) ' .Skip(1) to skip the header '
ListBox1.Items.Add(String.Join(vbTab, state))
Next
Demo (with output to console instead of filling a list box): https://dotnetfiddle.net/XQ3w2Z

Related

Unable to add item to a list

I am writing a function that will allow me to input some values and then this will return this as a list. This is my code currently.
Structure question
Dim asking As String
Dim answers As List(Of String)
End Structure
Private Function addQuestionToList(toAsk As String, answers() As String) As question
addQuestionToList.asking = toAsk
Dim listTemp As List(Of String)
For i As Integer = 0 To answers.Count - 1
listTemp.Add(answers(i))
Next
addQuestionToList.answers = listTemp
End Function
#Region "Quiz Questions"
Dim GTAQuestions As List(Of question)
Sub initializeGTAQuestions()
GTAQuestions.Add(addQuestionToList("Some Question", {"answer1", "answer2"}))
End Sub
#End Region
Change your code:
Dim GTAQuestions As List(Of question)
Sub initializeGTAQuestions()
GTAQuestions.Add(addQuestionToList("Some Question", {"answer1", "answer2"}))
End Sub
with this:
Dim GTAQuestions As New List(Of question)
Sub initializeGTAQuestions()
GTAQuestions.Add(addQuestionToList("Some Question", {"answer1", "answer2"}))
End Sub
You need to initialize each instance of the structure. One option is to include a custom new method in your structure, so your structure and function will look like this:
Structure question
Dim asking as String
Dim answers as List(Of String)
Public Sub New (ByVal _asking as String, ByVal _answers as List(Of String))
asking = _asking
answers = _answers
End Sub
End Structure
Private Function addQuestionToList(ByVal asking as String, ByVal answers() as String) as question
Dim lstAnswers as New List(Of String)
For Each answer As String in answers
lstAnswers.Add(answer)
Next
Return New question(asking, lstAnswers)
End Function

VB.net staggerred array of different types

I'm creating a Windows application in VB.NET in which needs to store a decent amount of associative information about different applications. I'm trying to find out what the best way to store this data.
After doing some research the best solution that I have found is to use arrays of objects, or dictionaries of objects.
Here is my data structure that needs to be stored:
var Info[AppID]['AppName']-> String (returns the app name as String)
['Exes'] -> Array of Strings
['RegKeys'] -> Array of Strings
['Versions'][VersionID]['PCID'] -> String
['Date'] -> DateTime
['Size'] -> Integer
The keys without quotes are dynamic and represent the actual AppID/VersionID, the keys in quotes are static (so the 2nd key will always have 'AppName' 'Exes' etc.
So for example:
Info[123ab]['Name'] = 'Internet Exploder'
['Exes'] = {'iexplore.exe', 'whatever.exe'}
['RegKeys'] = {'hkey/local machine .....'}
['Versions'][1]['PCID'] = 'My Desktop'
['Date'] = Jan 1 1960
['Size'] = 9001
would be declared and set up as
Dim appinfo As New Dictionary(Of String, Object)
Dim Lv2 As New Dictionary(Of String, Object)
Dim Exes As New List(Of String)(New String() {"iexplorer.exe", "whatever.exe"})
Dim RegKeys As New List(Of String)(New String() {"blah"})
Dim Directories As New List(Of String)(New String() {"c:\program files\internet explorer"})
Dim Name As String = "Internet Exploder"
Dim Versions As New Dictionary(Of String, Object)
Dim VersionsLv2 As New Dictionary(Of String, Object)
Dim VersionID As String = "1"
Dim PCID As String = "My Desktop"
Dim TheDate As Date = Now
Dim Size As Integer = 9001
VersionsLv2.Add("PCID", PCID)
VersionsLv2.Add("Date", TheDate)
VersionsLv2.Add("Size", Size)
Versions.Add("VersionID", VersionsLv2)
Lv2.Add("Name", Name)
Lv2.Add("RegKeys", RegKeys)
Lv2.Add("Directories", Directories)
Lv2.Add("Versions", Versions)
appinfo.Add("abc12", Lv2)
I'm just wondering if anyone knows any better way to do this? I kind of hate having to work from the top of the tree down in order to initialize the variable, but this seems to work ok.
Thank you very much for your input!
It looks like you should be defining two types to begin with, e.g.
Class App
Private ReadOnly _exes As New List(Of String)
Private ReadOnly _regKeys As New List(Of String)
Private ReadOnly _versions As New List(Of Version)
Public Property AppId() As String
Public Property AppName() As String
Public ReadOnly Property Exes() As List(Of String)
Get
Return _exes
End Get
End Property
Public ReadOnly Property RegKeys() As List(Of String)
Get
Return _regKeys
End Get
End Property
Public ReadOnly Property Versions() As List(Of Version)
Get
Return _versions
End Get
End Property
End Class
Class Version
Public Property VersionId() As String
Public Property PcId() As String
Public Property [Date]() As Date
Public Property Size() As Integer
End Class
In that example, the Version objects are stored in an App object in a simple collection and you would get them by index and use LINQ to get one by ID. If you wanted, you could make the Versions property a Dictionary instead. You could then create an array, List or Dictionary to store your App objects.

multidimensional array using list class and dictionary

//Declaration
Dim values As New List(Of Dictionary(Of String, String))()
I am trying to create a multidimensional array.
this is my code:
con.Open()
ccsfreader = ccsfcomm.ExecuteReader
ccsfreader.Read()
If ccsfreader.HasRows Then
Do
values.Add(New Dictionary(Of String, String)() From {{"CostCentre", ccsfreader.Item("CostCentre")}})
values.Add(New Dictionary(Of String, String)() From {{"ProcessDescription", ccsfreader.Item("ProcessDescription")}})
Loop While ccsfreader.Read()
End If
con.Close()
For Each value As Dictionary(Of String, String) In values
Dim CostCentre As String = value("CostCentre")
Dim ProcessDescription As String = value("ProcessDescription")
cmblaborcost.Items.Add(CostCentre)
Next
My error is:
The given key was not present in the dictionary.
i want an output like this:
1 => array(
CostCentre=>10.00
ProcessDescription=>"up"
)
2 => array(
CostCentre=>20.00
ProcessDescription=>"sided"
)
3 => array(
CostCentre=>110.00
ProcessDescription=>"cutted"
)
You have two dictionaries in the list. One of which contains only "CostCentre" key, and the other contains only "ProcessDescription" key. So when you try to access both keys from a dictionary, one key must be missing.
You may want to use List(Of Tuple(Of String, String)) instead of List(Of Dictionary(Of String, String)). This example works for me :
Dim values As New List(Of Tuple(Of String, String))
values.Add(Tuple.Create("a1", "a2"))
values.Add(Tuple.Create("b1", "b2"))
values.Add(Tuple.Create("c1", "c2"))
'generate array from List of Tuple'
Dim result = values.Select(Function(x) New String() {x.Item1, x.Item2}).ToArray()
For Each s As String() In result
Console.WriteLine(s(0) & ", " & s(1))
Next
And for your case, it could be something like this :
'example to add item to list'
Dim values As New List(Of Tuple(Of String, String))
......
If ccsfreader.HasRows Then
Do
'values.Add(Tuple.Create(ccsfreader.Item("CostCentre"), ccsfreader.Item("ProcessDescription"))'
values.Add(New Tuple(Of String, String)(ccsfreader.Item("CostCentre"), ccsfreader.Item("ProcessDescription")))
Loop While ccsfreader.Read()
End If
.......
'example to access item from list'
For Each value As Tuple(Of String, String) In values
Dim CostCentre As String = value.Item1
Dim ProcessDescription As String = value.Item2
cmblaborcost.Items.Add(CostCentre)
Next

How to set a new property for an array in vb.net?

Dim SteamGames As New Dictionary(Of String, String)
For Each Game As String In System.IO.Directory.GetDirectories(Me.tb_SteamDir.Text)
SteamGames.Add(Game, System.IO.Path.GetFileName(Game))
Next Game
For Each Pair As KeyValuePair(Of String, String) In SteamGames
dgv_Table.Rows.Add(Pair.Key)
dgv_Table.Rows.Add(Pair.Value)
Next Pair
I am getting both the folder directory and the folder's name in the same column, how do I make them separate into different columns?
This should load the ComboBox and the DataGridView as you requested:
Dim DT As New DataTable
DT.Columns.Add("Full Path")
Dim GameNames_Master As New List(Of String)
For Each Dir As DirectoryInfo In New DirectoryInfo(Me.tb_SteamDir.Text).GetDirectories
GameNames_Master.Add(Dir.Name)
DT.Rows.Add(New Object() {Dir.FullName})
Next Dir
dgv_Table.DataSource = DT
Me.cb_Games.DataSource = GameNames_Master

Extract part of a text file for usage in vb.net

Ok. I need to store some records in a file namely data.dat.
Records in the file are sorted by date values. Each block of record starts with its date value along with a $ sign to indicate that a new block of record starts here and ends with a "#" sign to indicate end of the record block.
A sample of a record block would be:
$22/08/2013
(data)
(data)
(data)
#
The file data.dat contains several blocks like this, how can I extract each block in the file storing each in an array using vb.net?
Instead of an array i would use a List(Of T). You could create a custom class:
Class Record
Public Property DateValue As DateTime
Public Property Data As New List(Of String)
End Class
Here's a possible loop to initialize the list from your file:
Dim allData As New List(Of Record)
Dim currentRecord As Record = Nothing
Dim currentData As List(Of String) = Nothing
For Each line In File.ReadLines("data.dat")
If line.StartsWith("$") Then
Dim dt As DateTime
If Date.TryParse(line.Substring(1), dt) Then
currentRecord = New Record()
currentRecord.DateValue = dt
currentData = New List(Of String)
currentRecord.Data = currentData
End If
ElseIf currentRecord IsNot Nothing Then
If line.EndsWith("#") Then
allData.Add(currentRecord)
Else
currentData.Add(line)
End If
End If
Next
It looks to me a Tuple quartet would be ready made for this.
Dim Record As New List(Of Tuple(Of DateTime, String, String, Integer))
Then each field can be accessed by it's item number:
Record(0).Item1

Resources