Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Implement Map Function in VB.NET

I am trying to implement Map in VB.NET with the functionality described in this answer.

It should take an IEnumerable(Of TIn) and a Function(Of TIn, TOut), execute the function over every element, and return a new IEnumerable(Of TOut).

I know VB.NET is not a true functional language. I have business requirements, but would still like to use some functional tidbits, especially in conjunction with LINQ.

A similar question is asked here, but the question and answer are actually about implementing Each.

like image 504
Z_AHK Avatar asked Jul 03 '26 06:07

Z_AHK


1 Answers

Thanks to @Sehnsucht for pointing out that there already is a Map function in LINQ that is called Select.

Here is my original answer that is definitely not as good as what the smart people designing LINQ created:

Here is a an extension method that can be placed in a Module in the root namespace:

Module Extensions
    <System.Runtime.CompilerServices.Extension> _
    Public Function Map(Of TIn, TOut)(ByVal a As IEnumerable(Of TIn), ByVal f As Func(Of TIn, TOut)) As IList(Of TOut)
        Dim l As New List(Of TOut)
        For Each i As TIn In a
            Dim x = f(i)
            l.Add(x)
        Next
        Return l
    End Function
End Module

It can be called like:

Sub Main()
    Dim Test As New List(Of Double) From {-10000000, -1, 1, 1000000}
    Dim Result1 = Test.Map(Function(x) x.ToString("F2"))
    'Result1 is of type IList(Of String)
    Dim Result2 = Test.Map(AddressOf IsPositive)
    'Result2 is of type IList(Of Boolean)
    Dim Result3 = Map(Test, Function(y) y + 1)
    'Result3 is of type IList(Of Double)
End Sub

Private Function IsPositive(d As Double) As Boolean
    If d > 0 then
        Return True
    Else
        Return False
    End If
End Function

I return an IList(Of TOut) because it is more useful for my purposes (and, well, it's returning a list!). It could return an IEnumerable(Of TOut) by changing the return line to Return l.AsEnumerable(). It accepts an IEnumerable(Of TIn) instead of an IList(Of TIn) so it can accepts a wider range of inputs.

I'm open to anybody suggesting performance improvements.

like image 77
Z_AHK Avatar answered Jul 06 '26 04:07

Z_AHK