Reputation: 11
The question is how to present nicely working code of DispList and RotateList functions using LINQ eventually Lambda. Thank you in advance
Class CalcProc
Property Year As Integer
Property Type As String
Property Count As Integer
Property Total As Integer
Property Proc As Decimal
End Class
Sub CreateListOfT()
Dim List As New List(Of CalcProc)
List.Add(New CalcProc With {.Year = 2013, .Type = "A", .Count = 12, .Total = 20, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2013, .Type = "B", .Count = 22, .Total = 30, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2014, .Type = "C", .Count = 32, .Total = 40, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2015, .Type = "D", .Count = 42, .Total = 50, .Proc = calcP(.Count, .Total)})
List.Add(New CalcProc With {.Year = 2016, .Type = "E", .Count = 52, .Total = 60, .Proc = calcP(.Count, .Total)})
DispListOfT(List)
RotateListOfT(List)
End Sub
Private Function DispListOfT(Of T)(ByVal dList As IList(Of T))
If Not dList.Any Then
MsgBox("NOTHING to display!", vbCritical, MethodBase.GetCurrentMethod.Name())
End
End If
Dim fields() = dList.First.GetType.GetProperties
Dim ListColumns = (From x In fields Select x.Name).ToList()
Console.WriteLine(String.Join(",", ListColumns.ToArray))
Dim sb As New Text.StringBuilder
For Each item In dList
sb.Length = 0
For Each field In fields
Dim p = item.GetType.GetProperty(field.Name)
sb.Append(p.GetValue(item, Nothing)) : sb.Append(",")
Next
Console.WriteLine(Left(sb.ToString, sb.Length - 1))
Next
End Function
Public Function RotateListOfT(Of T)(ByVal dList As IList(Of T))
Dim sa As New Text.StringBuilder
Dim fields() = dList.First.GetType.GetProperties
Dim dCount As Integer
Dim Modulo As Integer = dList.Count \ 4
For i As Integer = 0 To Modulo - 1
For Each field In fields
sa.Append(field.Name)
sa.Append(vbTab)
For Each item In dList
If dCount Mod Modulo = i Then
Dim p = item.GetType.GetProperty(field.Name)
sa.Append(p.GetValue(item, Nothing))
sa.Append(vbTab)
End If
dCount += 1
Next
Console.WriteLine(sa.ToString)
sa.Length = 0
Next
Next
End Function
Function calcP(a As Integer, b As Integer) As Decimal
Return Round(a * 100.0 / b, 2)
End Function
List(Of T)
Year, Type, Count, Total, Proc
2013,A,12,20,60
2013,B,22,30,73.33
2014,C,32,40,80
2015,D,42,50,84
2016,E,52,60,86.67
Rotated List(Of T)
Year 2013 2013 2014 2015 2016
Type A B C D E
Count 12 22 32 42 52
Total 20 30 40 50 60
Proc 60 73.33 80 84 86.67
Upvotes: 1
Views: 124
Reputation: 26907
Here is my re-write of your Sub
s. While you could replace the remaining For Each
loops with List.ForEach
, there is no advantage to doing so, and I think it is less clear. LINQ is really best for transforming sequences into results, which you then use for I/O.
Since you know the parameter dList
is a IList(Of T)
, you know that every member will of a T
with the same properties, so no reason to retrieve the properties for each item.
Finally I used lambda syntax for the LINQ as it lends itself to being nested in other function calls.
Public Sub DispListOfT(Of T)(ByVal dList As IList(Of T))
If Not dList.Any Then
'MsgBox("NOTHING to display!", vbCritical, MethodBase.GetCurrentMethod.Name())
Return
End If
Dim props = dList.First.GetType.GetProperties
Console.WriteLine(String.Join(",", props.Select(Function(p) p.Name)))
For Each item In dList
Console.WriteLine(String.Join(",", props.Select(Function(p) p.GetValue(item))))
Next
End Sub
Public Sub RotateListOfT(Of T)(ByVal dList As IList(Of T))
For Each prop In dList.First.GetType.GetProperties
Console.Write(prop.Name)
Console.Write(vbTab)
Console.WriteLine(String.Join(vbTab, dList.Select(Function(item) prop.GetValue(item))))
Next
End Sub
If I were writing a program to do this, I would probably separate rotation of the List
from outputting the rotated List
. Also, it should be very unusual to use Reflection to get property names from types, you should already know the types you are dealing with and add the output methods to the class for the type, unless your program is dealing with lots of lists of different classes for some reason.
Upvotes: 2