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.