vblang icon indicating copy to clipboard operation
vblang copied to clipboard

[Proposal] LinQ with a multiple collections result

Open VBAndCs opened this issue 3 years ago • 7 comments

I want to use one LinQ querty to obtain more than one list in the result (which is better performance than iterating the collection many times to get a single list at a time). I suggest to allow using multiple Select clauses in the query (gives an error currently):

Dim result = From s In Students
         Select s.ID
         Select s.Name

Which can be lowered to:

    Dim ids As New List(Of Integer)
    Dim names As New List(Of String)

    For Each s In Students
            ids.Add(s.ID)
            names.Add(s.Name)
    Next
      result = New With {.IDs = ids, .Names = names}

Note: using the #564 proposal, the suggested syntax can be rewritten as:

Dim result = From Students
         Select ID
         Select Name

I also suggest to alow us to choose another collection type (other the default List(Of T)):

From Student
Select Id 
Select Name As ObservableCollection(Of String)

Which can be lowered to:

    Dim ids As New List(Of Integer)
    Dim names As New ObservableCollection(Of String)

    For Each s In Students
            ids.Add(s.ID)
            names.Add(s.Name)
    Next
      result = New With {.IDs = ids, .Names = names}

VBAndCs avatar Sep 12 '20 18:09 VBAndCs

What advantages would this have over returning a list of tulples or anonymous types?

jrmoreno1 avatar Sep 13 '20 00:09 jrmoreno1

If you need different (columns) of the data, to use each as a param to different methods (such Average(StudentGrads As List(of integer)), Print(Names As List(Of String))), you have to use more than one query ( = iterations). If you get a list of tuples, you need more queries to get individual lists.

VBAndCs avatar Sep 13 '20 02:09 VBAndCs

        Dim lst = New List(Of Integer) From {1,2,3,4,5,6,7,8,9,10}
	Dim m = lst.Select(Function(i)  (x:=i, y:=i.ToString()))

	Dim tp = m.Aggregate((ListI:=New List(Of Integer), ListS:=New List(Of String)), 
		Function(seed, src)
			Console.Writeline("here")
			seed.ListI.Add(src.x)
			seed.ListS.Add(src.y)
			Return seed
		End Function)
	Console.WriteLine(tp.ListI.Count)
	Console.WriteLine(tp.ListS.Count)

List of tuples to a tuple of lists, iterated just once. If you need to do it a lot, you could turn it into a generic extension method .

jrmoreno1 avatar Sep 13 '20 05:09 jrmoreno1

Such complexity is why I am re-designing the language! Try to do this:

Dim result = From Students
         Select ID
         Select Name
         Select Grades
         Select Sports

Please, lets think VB-ly.

VBAndCs avatar Sep 13 '20 13:09 VBAndCs

Dim temp= From Students
         Select (ID, Name, Grades,Sports)
Dim result = temp.SplitTuple

Public Module ext
	<Extension>
	Public Function SplitTuple(Of T1, T2, T3, T4)(tps As IEnumerable(Of (T1, T2, T3, T4))) As (List(Of T1), List(Of T2), List(Of T3), List(Of T4))
		Dim retVal = (New List(Of T1), New List(Of T2), New List(Of T3), New List(Of T4))
		Dim tp = tps.Aggregate(retVal,
		Function(seed, src)
			Console.Writeline("here")
			seed.Item1.Add(src.Item1)
			seed.Item2.Add(src.Item2)
			seed.Item3.Add(src.Item3)
			seed.Item4.Add(src.Item4)
			Return seed
		End Function)
		Return RetVal
	End Function

	<ExtensionAttribute>
	Public Function SplitTuple2(Of T1, T2, T3, T4)(tps As IEnumerable(Of (T1, T2, T3, T4))) As (IEnumerable(Of T1), IEnumerable(Of T2), IEnumerable(Of T3), IEnumerable(Of T4))
			Return (tps.Select(Function(tp) tp.Item1), tps.Select(Function(tp) tp.Item2), tps.Select(Function(tp) tp.Item3), tps.Select(Function(tp) tp.Item4))
	End Function
	
End Module

As for thinking VB-ly, you do as much to kill my hope of VB being revived as MS does. I want good things for the language, not the kitchen sink, and you're tossing out language changes for every minor thing you happen to run across. Option Infer Turbo (aka #172) would be awesome, this suggestion is worse than yawnsome -- I don't think I've ever had a desire to do what you're suggesting, and if I did, I would directly use the method used in the last extension method because MULTIPLE ITERATIONS is not a problem. You can't avoid multiple iterations, either you go through all of the student names or you don't. Lazy evaluations means that multiple iterations would only matter if you were turning it into a list and then filtering it even more.

jrmoreno1 avatar Sep 13 '20 14:09 jrmoreno1

You are free to wast your life writing whatever code you want. I am seeking a smart language that adapts to fit me, not asking millions of programmers to fits its solid rules. In fact that is exactly C# performance-oriented User-unfriendly syntax, and VB should never be that! I don't care if we made 10 million changes in the lang. In fact VB should be re-designed from ground up, and I am glad the team abandoned it. I said I am sharing these suggestions to new alternatives that can emerge of the language, and I have an intent to implement my vision myself. You can't stick with a dead language rules, because they what killed the language in first place. And by the way: C# fits you more, and I advise you to embrace it, as you are thinking the same. The only thing that VB can offer to the world is smart compact readable syntax. If the API can do it all regardless the lang, so, MS took the right decision to stop wasting its money over a duplicate no benefit language, and embrace a child language like F# that offers new things. It is strange that VB community didn't understand yet what happened last March and what facts it implies. In fact this started in 2017, when MS put F# above VB in priority despite VB popularity. This is why I was crying out loud that VB is dying since my first issues here, and asking for many enhancements to evolve the lang and reintroduce it to a new generation.

VBAndCs avatar Sep 13 '20 15:09 VBAndCs

By the way, I am publishing a series of videos on YouTube (17 videos so far) to introduce Small Basic to Arabic children. But this will not benefit VB.NET if they grow up to find it still stuck to desktop, with a syntax that is not less complex (but verbosely longer) than C#'s!

VBAndCs avatar Sep 13 '20 15:09 VBAndCs