0

I have 3 list of strings.

List1 - Student Name            List2 - Student School          List3 - Student Location
Student 1                       Student 1 School                Student 1 Location
Student 2                       Student 2 School                Student 2 Location
Student 3                       Student 3 School                Student 3 Location
Student 4                       Student 4 School                Student 4 Location
Student 5                       Student 5 School                Student 5 Location

And a structure StudentDetails

Public Structure StudentDetails()
    Public StudentName As String
    Public StudentSchool As String
    Public StudentLocation As String
End Structure

I want to make the first 3 list to List of StudentDetails

I have used the following code to do this

Dim StudentDetailsList As New List(Of StudentDetails)
For i = 0 to List1.Count - 1
    Dim StudentDetail As New StudentDetail
    With StudentDetail
        .StudentName = List1(i)
        .StudentSchool = List2(i)
        .StudentLocation = List3(i)
    End With
    StudentDetailsList.Add(StudentDetail)
Next

Is there a better way to do this using Linq or some other method?

Kannan Suresh
  • 4,573
  • 3
  • 34
  • 59

2 Answers2

1

There are many ways to do that, some easier to read than others.

First, I would make StudentDetails a class instead of a structure (see, e.g., When should I use a struct instead of a class?.

Now that you have a class, you can give it a New constructor with parameters, as used in the third example here:

Option Infer On
Option Strict On

Module Module1

    Public Class StudentDetails
        Public Name As String
        Public School As String
        Public Location As String

        Public Sub New()
            ' empty constuctor
        End Sub

        Public Sub New(name As String, school As String, location As String)
            Me.Name = name
            Me.School = school
            Me.Location = location
        End Sub

        ' make it easy to represent StudentDetails as a string...
        Public Overrides Function ToString() As String
            Return $"{Me.Name} {Me.School} {Me.Location}"
        End Function

    End Class

    Sub Main()

        Dim list1 As New List(Of String) From {"Adam", "Betty", "Charles", "Wilma"}
        Dim list2 As New List(Of String) From {"Ace", "Best", "Classy", "Wacky"}
        Dim list3 As New List(Of String) From {"Attic", "Basement", "Cellar", "Windowledge"}

        ' a not-very tidy example using Zip:
        Dim StudentDetailsList = list1.Zip(list2, Function(a, b) New With {.name = a, .school = b}).Zip(list3, Function(c, d) New StudentDetails With {.Name = c.name, .School = c.school, .Location = d}).ToList()

        ' one way of writing out the StudentDetailsList...
        For Each s In StudentDetailsList
            Console.WriteLine(s.ToString())
        Next

        StudentDetailsList.Clear()

        ' a bit cleaner using a loop:
        For i = 0 To list1.Count() - 1
            StudentDetailsList.Add(New StudentDetails With {
                                   .Name = list1(i),
                                   .School = list2(i),
                                   .Location = list3(i)})
        Next

        ' another way of writing out the StudentDetailsList...
        Console.WriteLine(String.Join(vbCrLf, StudentDetailsList))


        StudentDetailsList.Clear()

        ' easy to write with a New constructor, but not necessarily as easy to read as the previous example:
        For i = 0 To list1.Count() - 1
            StudentDetailsList.Add(New StudentDetails(list1(i), list2(i), list3(i)))
        Next

        Console.WriteLine(String.Join(vbCrLf, StudentDetailsList))

        Console.ReadLine()

    End Sub

End Module

I used the $ string formatter in the .ToString() method: it was introduced with VS2015, so if you are using an earlier version you can use String.Format("{0} {1} {2}", Me.Name, Me.School, Me.Location) instead.

As a note on naming the properties of StudentDetails, the "Student" in StudentName, StudentSchool and StudentLocation is redundant.

Community
  • 1
  • 1
Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • This is just a sample data. Real data is not details of students. However, I will keep note of your tips and thanks for explaining why I should use class instead of structure. – Kannan Suresh Apr 28 '16 at 03:40
0

Well, you can use an overload of Select extension method to projects each element of one of the list into a new StudentDetail by incorporating the element's index. Assuming the three lists have the same amount of elements, you can do the following:

// using C#
var result=List1.Select((e,i))=>new StudentDetail 
                                    {
                                      StudentName =e,
                                      StudentSchool = List2[i],
                                      StudentLocation = List3[i]
                                    }).ToList();

I think in Vb would be (sorry, I'm a c# programmer):

 Dim StudentDetailsList=List1.Select(Function(e, i) _
                                         New StudentDetail
                                         With StudentDetail
                                             .StudentName = e
                                             .StudentSchool = List2(i)
                                             .StudentLocation = List3(i)
                                         End With).ToList();

But using a for is not a bad solution, in many cases is more readable.

ocuenca
  • 38,548
  • 11
  • 89
  • 102