0

I am trying to accomplish the following in VB.net:

' Create multidimensional array holding parents and childs 

[100] Parent1
    [101] Child1
    [102] Child2
[200] Parent2
    [201] Child1
[300] Parent3
    [301] Child1
    [302] Child2
    [303] Child3

' Loop through multidimensional array

For Each Parent in Array
    Print parent_id parent_name

    For each Child in Parent
        Print child_id child_name
    Next
Next

The output should then be:

100 Parent1
101 Child1
102 Child2
200 Parent2
201 Child1
300 Parent1
301 Child1
302 Child2
303 Child3

I know a one dimensional array in BV.net is created like:

Dim Parents As New Dictionary(Of Integer, String) From { 
    {100, "Parent1"}, 
    {200, "Parent2"},
    {300, "Parent3"}
}

However, I cannot figure out how to expand this to also hold the childs.

Question 1: How do I eed to update the array above to also hold the children for each parent item?

The For Each loop is written in pseudo-code.

Question 2: How does one loop through the multidimensional array to get the output I need?

1
  • how does your loop fail you? what are the results? are parent and child classes? where is the code? Commented Oct 2, 2014 at 23:32

3 Answers 3

1

I know a one dimensional array in BV.net is created like:

Dim Parents As New Dictionary(Of Integer, String) From { 
    {100, "Parent1"}, 
    {200, "Parent2"},
    {300, "Parent3"}
}

That’s a dictionary – a mapping of unique keys to values – and not a one-dimensional array. If you just want to iterate over it (especially if you want to do so in order), a list of tuples (Tuple(Of Integer, String)) or KeyValuePairs is probably more appropriate:

Dim parents As New List(Of Tuple(Of Integer, String)) From {
    Tuple.Create(100, "Parent1"),
    Tuple.Create(200, "Parent2"),
    Tuple.Create(300, "Parent3")
}

You can extend that into a three-item tuple to give them each children:

Dim parents As New List(Of Tuple(Of Integer, String, List(Of Tuple(Integer, String))) From {
    Tuple.Create(100, "Parent1", New List(Of Tuple(Integer, String)) From { Tuple.Create(101, "Child1"), Tuple.Create(102, "Child2") }),
    Tuple.Create(200, "Parent2", New List(Of Tuple(Integer, String)) From { Tuple.Create(201, "Child1") }),
    …
}

and to iterate over it,

For Each parent In parents
    Console.WriteLine("[{0}] {1}", parent.Item1, parent.Item2)

    For Each child In parent.Item3
        Console.WriteLine("    [{0}] {1}", child.Item1, child.Item2)
    Next
Next

Those aren’t very descriptive names, though, and you can always just make your own classes.

Class Parent
    Public Property Number As Integer
    Public Property Name As String
    Public Property Children As New List(Of Child)()

    Public Sub New(number As String, name As String)
        Me.Number = number
        Me.Name = name
    End Sub
End Class

Class Child
    Public Property Number As Integer
    Public Property Name As String

    Public Sub New(number As String, name As String)
        Me.Number = number
        Me.Name = name
    End Sub
End Class

Depending on how these are related, it might be appropriate for one to inherit from the other. Then, for convenience, you can make the parent enumerable; for even more convenience, you can give it an Add method, which will allow the From syntax to be used as well:

Class Parent
    Implements IEnumerable(Of Child)

    Public Property Number As Integer
    Public Property Name As String
    Public Property Children As New List(Of Child)()

    Public Sub New(number As String, name As String)
        Me.Number = number
        Me.Name = name
    End Sub

    Public Sub Add(child As Child)
        Me.Children.Add(child)
    End Sub

    Public Function GetEnumerator() As IEnumerator(Of Child) Implements IEnumerable(Of Child).GetEnumerator
        Return Me.Children.GetEnumerator()
    End Function

    Private Function GetEnumerator_() As IEnumerator Implements IEnumerable.GetEnumerator
        Return Me.GetEnumerator()
    End Function
End Class

and:

Dim parents As New List(Of Parent) From {
    New Parent(100, "Parent1") From {
        New Child(101, "Child1"),
        New Child(102, "Child2")
    },
    …
}

My syntax might not be quite right on these, but you get the idea.

Sign up to request clarification or add additional context in comments.

Comments

0

Sounds like you need more than just a Dictionary or a multi-dimensional array: you need a class.

Your parent objects have at least three attributes:

 ID
 Name
 Collection of child objects

While you could theoretically handle all that in a multi-dimensional array of objects, you'll tie yourself in knots trying to keep it all straight. What you need is a class with properties representing those three attributes. Your parent and child objects would both be instances of this class: the child objects just wouldn't have child objects of their own.

If you aren't familiar with the concept of a class, you'll need to do some reading. Read about classes, about properties, and about collection classes. You might want to pay special attention to the ArrayList class, as it might be very helpful. (The generic List<T> class would be even more useful, but that's a more advanced topic.)

Comments

0

This isn't a very efficient solution - it compares every family member with every other one. However, it does what you need and should teach you a bit about how arrays work.

  Sub ShowFamily()
    Dim strFamily(-1, -1) As String '0-based (indices start at zero). first index is the person, second index are the properties associated with the person
    '(*, 0) = Person's name
    '(*, 1) = Person's ID
    '(*, 2) = Person's parent's ID

    '1. Fill array with data
    Call LoadFamily(strFamily)
    '2. Go through the array looking for family members that have no parents
    For i As Integer = 0 To strFamily.GetUpperBound(0)
      If strFamily(i, 2) = "" Then
        '3. Found a parent. Output their name
        Debug.WriteLine(String.Format("{0} {1}", strFamily(i, 1), strFamily(i, 0)))
        '4. Go through the array a second time, looking for this parent's children
        For j As Integer = 0 To strFamily.GetUpperBound(0)
          If strFamily(j, 2) = strFamily(i, 1) Then 'compare child's parent ID with parent's ID - do they match?
            'found a match - output the child
            Debug.WriteLine(String.Format("    {0} {1}", strFamily(j, 1), strFamily(j, 0)))
          End If
        Next j
      End If
    Next i
  End Sub

  Sub LoadFamily(ByRef strFamily(,) As String)
    ReDim strFamily(9, 2) '9 members
    strFamily(0, 0) = "Parent1"
    strFamily(0, 1) = "100"
    strFamily(0, 2) = "" 'no parent
    '
    strFamily(1, 0) = "Parent1Child1"
    strFamily(1, 1) = "101"
    strFamily(1, 2) = "100" 'Parent1
    '
    strFamily(2, 0) = "Parent1Child2"
    strFamily(2, 1) = "102"
    strFamily(2, 2) = "100" 'Parent1
    '
    strFamily(3, 0) = "Parent2"
    strFamily(3, 1) = "200"
    strFamily(3, 2) = "" 'no parent
    '
    strFamily(4, 0) = "Parent2Child1"
    strFamily(4, 1) = "201"
    strFamily(4, 2) = "200" 'Parent2
    '
    strFamily(5, 0) = "Parent3"
    strFamily(5, 1) = "300"
    strFamily(5, 2) = "" 'no parent
    '
    strFamily(6, 0) = "Parent3Child1"
    strFamily(6, 1) = "301"
    strFamily(6, 2) = "300" 'Parent3
    '
    strFamily(7, 0) = "Parent3Child2"
    strFamily(7, 1) = "302"
    strFamily(7, 2) = "300" 'Parent3
    '
    strFamily(8, 0) = "Parent3Child3"
    strFamily(8, 1) = "303"
    strFamily(8, 2) = "300" 'Parent3
    'Add a third child to parent 1, to demonstrate that we are actually matching parents to children
    strFamily(9, 0) = "Parent1Child3"
    strFamily(9, 1) = "103"
    strFamily(9, 2) = "100" 'Parent1
  End Sub

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.