I have an inline lambda expression that I would like to use throughout my application. I just can't seem to find a reference on how to do this with more parameters than the element being tested. Here is a quick example of what I currently have.
Private Sub Test()
Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
Dim Search As String = "*Jo*"
Dim Result = List.Where(Function(Name) Name Like Search)
End Sub
I know the IEnumerable.Where
accepts a method with the element type as a parameter and a returning boolean.
Private Sub Test()
Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
Dim Search As String = "*Jo*"
Dim Result = List.Where(AddressOf FindName)
End Sub
Private Function FindName(Name As String) As Boolean
Return Name Like "*Jo*"
End Function
I would like to pass the Search variable into FindName as well. I just can't seem to get the syntax figured accomplish this. The only working solution I've come up with is passing everything to a function to perform the original statement.
Private Sub Test()
Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
Dim Search As String = "*Jo*"
Dim Result = FindName(List, Search)
End Sub
Private Function FindName(List As IEnumerable(Of String), Search As String) As IEnumerable(Of String)
Return List.Where(Function(Name) Name Like Search)
End Function
Don't feel obligated to answer in VB.
The nice thing with lambda expressions is that they allow closures to automatically capture variables that are local to your scope. For example (pardon the C#):
List.Where(i => FindName(i, Search));
In the above code, the Search
variable is actually being encapsulated in a closure. If you want to just pass a method, you'll have to simulate what closures do with an actual class structure:
public class NameFinder
{
private string _search;
public NameFinder(string search) {
_search = search;
}
public bool Match(string item) {
// C# equivalent of "return item LIKE _search"
}
}
// Usage
var nameFinder = new NameFinder(Search);
List.Where(nameFinder.Match);
However, this strategy is only useful in a small subset of cases. I find it's usually best to just use a lambda expression that passes the appropriate variables into the function that does all the work.
I would use an extension method:-
Module Module1
Sub main()
Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
Dim Search As String = "*Jo*"
Dim Result = List.FindName(Search)
End Sub
End Module
Public Module Extensions
<System.Runtime.CompilerServices.Extension()>
Public Function FindName(List As IEnumerable(Of String), Search As String) As IEnumerable(Of String)
Return List.Where(Function(Name) Name Like Search)
End Function
End Module
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With