Page 1 of 1

## Predicates (For vb.net 2.0 and above) Rate Topic:     1 Votes //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'https://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=313102&amp;s=30ddeec28531c67631d68018f060aa08&md5check=' + ipb.vars['secure_hash'], cur_rating: 5, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 thava Reputation: 180
• Posts: 1,607
• Joined: 17-April 07

Posted 22 February 2013 - 03:02 AM

What is a Predicate?
As per Microsoft Explanation
A function that defines a set of criteria and determines whether the specified object meets those criteria.

To me, simply said that it is a Function which has only one parameter and it always return a boolen value
based on the logical operations performed for that parameter

Why predicate?
Most of the time people ask this question in the web
let us consider this , a client has list of integers he want's to the count following
1) the multiple of 5
2) the multiple of 10,
3) the multiple of 5 and not multiple of 10
i have created a list of integers,using the following code
```        lstNumbers = New List(Of Integer)
For i = 0 To 10000
Dim r As New Random
Dim rnd As Integer = r.Next(0, i)
Next

```

Now,i Want to get the multiple of 5
```	Dim Lstfive As New List(Of Integer)
For Each num As Integer In lstNumbers
If num Mod 5 = 0 Then
End If
Next

```

this result contains the zero values
since this results contains with 0 values i want to eliminate zeros
For this i have two options
1) create the result list again with the new for loop
2) delete the zeros from the result list using a new for loop
i go with the first one and create the result again
```      Dim lstFive As New List(Of Integer)
For Each num As Integer In lstNumbers
If num Mod 5 = 0 And num <> 0 Then
End If
Next
MessageBox.Show(lstFive.Count)

```

Now i want to get the Multiple of 10
```        Dim lstTen As New List(Of Integer)
For Each num As Integer In lstNumbers
If num Mod 10 = 0 And num <> 0 Then
End If
Next
MessageBox.Show(lstTen.Count)

```

Now i want to get the count of the multiple of 5 and not the Multiple of 10 for this i have two option
1) Create the result list again with the new for loop
2) Just subtract the lstFive.count-lstTen.count
If I go with first option I need to create a Loop again so I am going to choose the second option
Since I have lstFive and lstTen both lists are filled
```       MessageBox.Show(lstFive.Count - lstTen.Count)

```

Now i want to add an extra option with this program let the user choose choice what he want, either it's multiple of 5 or multiple of 10 or multiple of 5 but not multiple of 10
Now the code look like this (since I used the winform i used Radio options here)
```        Dim res As New List(Of Integer)
For Each num As Integer In lstNumbers
If num Mod 5 = 0 Then
End If
Next
For Each num As Integer In lstNumbers
If num Mod 5 = 0 And num <> 0 Then
End If
Next
End If
MessageBox.Show(res.Count)

```

Now just think if we want to work out this in an array of numbers and perform the same operation again, what will happen the code will get double again
you may said that create a function or procedure to reduce the code but list of numbers and array of numbers are not equal, so we need to convert the array to list and pass to that function we need a conversion here

Adding some more conditions then the whole code will become looks like the following code
```	Dim res As New List(Of Integer)
If Rdoby5.Checked = True Then
For Each num As Integer In lstNumbers
If num Mod 5 = 0 Then
End If
Next
ElseIf rdoby10.Checked = True Then
For Each num As Integer In lstNumbers
If num Mod 10 = 0 Then
End If
Next
ElseIf Rdoby5NotZero.Checked = True Then
For Each num As Integer In lstNumbers
If num Mod 5 = 0 And num <> 0 Then
End If
Next
ElseIf rdoby10NotZero.Checked = True Then
For Each num As Integer In lstNumbers
If num Mod 10 = 0 And num <> 0 Then
End If
Next
ElseIf RdoNonZeronumbers.Checked = True Then
For Each num As Integer In lstNumbers
If num <> 0 Then
End If
Next
Else
For Each num As Integer In lstNumbers
If num Mod 5 = 0 And num Mod 2 <> 0 Then
End If
Next
End If
MsgBox(res.Count)

```

Now let us see how predicate works, i already give a little explanation about Predicate in my point of view
a predicate is a function which returns always a boolean value with one parameter so its look like this
```
Private/Public Function <Function Name>(ByVal X As <Any Type you want to process>) As Boolean
'Process x here and return the boolean
Return (True/ False)
End Function

```

Let's go from the begining

i Want to get the multiple of 5 For that i create a function like this

```Private Function multipleOfFive(ByVal i As Integer) As Boolean
Return (i Mod 5 = 0)
End Function

```

Take a close look of the function it has only one parameter which is integer since i am going to work with integer and the return type is Boolean

Now how can i use this
```	Dim lstfive As New List(Of Integer)

```

you can use the same function for the array also

```

```

since this results contains with 0 values i want to eliminate zeros
so I have to create a new function from the previous function and refine the result
```	Private Function IsNonZero(i As Integer) As Boolean
Return i <> 0
End Function

Private Function multipleOfFiveNotZero(ByVal i As Integer) As Boolean
Return multipleOfFive(i) And IsNonZero (i)
End Function

Dim lstFive As New List(Of Integer)

MessageBox.Show(lstFive.Count)

```

Multiple of 10
For that I create a new function from the previous function
```    	Private Function multipleOfTen(ByVal i As Integer) As Boolean
Return multipleOfFiveNotZero(i) And (i Mod 2 = 0)
End Function

Dim lstTen As New List(Of Integer)
MessageBox.Show(lstTen.Count)

```

Multiple of 5 but not Multiple of 10
```        Dim lstFiveOnly As New List(Of Integer)
'since it contains the Multiple of 10 remove the 10
MsgBox(lstFiveOnly.Count)

```

if you look at the above code, just the same function(multipleofTen) is used to Remove the numbers also Think how much code is reduced and how much readable is this

Now look at the One more Special
i want to add an extra option with this program let the user choose the choice what he want, either it's multiple of 5 or multiple of 10 or multiple of 5 but not multiple of 10 Now the code look like this(since i used the winform i used Radio options here)
```        Dim res As New List(Of Integer)
Dim lstfive As New List(Of Integer)
If Rdoby5.Checked = True Then
ElseIf rdoby10.Checked = True Then
ElseIf Rdoby5NotZero.Checked = True Then
ElseIf rdoby10NotZero.Checked = True Then
ElseIf RdoNonZeronumbers.Checked = True Then
Else
End If
MsgBox(res.Count)

```

you may thought "is it a special one", well that's not the special one, adding one more implementation to maintain readability of the code I re write it with the predicate declaration see the following code
On the whole it's look like this
```   Private Sub btnByPredicate_Click(sender As System.Object, e As System.EventArgs) Handles btnByPredicate.Click
Dim res As New List(Of Integer)
'Dim lstfive As New List(Of Integer)
'If Rdoby5.Checked = True Then
'ElseIf rdoby10.Checked = True Then
'ElseIf Rdoby5NotZero.Checked = True Then
'ElseIf rdoby10NotZero.Checked = True Then
'ElseIf RdoNonZeronumbers.Checked = True Then
'Else
'End If
'MsgBox(res.Count)

Dim prdNumbers As System.Predicate(Of Integer)
If Rdoby5.Checked = True Then
ElseIf rdoby10.Checked = True Then
ElseIf Rdoby5NotZero.Checked = True Then
ElseIf rdoby10NotZero.Checked = True Then
ElseIf RdoNonZeronumbers.Checked = True Then
Else
End If
MsgBox(res.Count)

End Sub

Private Function IsNonZero(i As Integer) As Boolean
Return i <> 0
End Function

Private Function multipleOfFive(ByVal i As Integer) As Boolean
Return (i Mod 5 = 0)
End Function

Private Function multipleOfTen(ByVal i As Integer) As Boolean
Return multipleOfFive(i) And (i Mod 2 = 0)
End Function

Private Function multipleOfFiveNotZero(ByVal i As Integer) As Boolean
Return multipleOfFive(i) And IsNonZero(i)
End Function

Private Function multipleOfTenNotZero(ByVal i As Integer) As Boolean
'Return multipleOfFiveNotZero(i) And (i Mod 2 = 0)
Return multipleOfTen(i) And IsNonZero(i)
End Function

Private Function multipleOfFiveNotTen(ByVal i As Integer) As Boolean
'Return multipleOfFive(i) And (i Mod 10 <> 0)
'Return multipleOfFive(i) And Not multipleOfTen(i)
Return multipleOfFive(i) And (i Mod 2 <> 0)
End Function

```

Spoiler

Now consider the situation after a long time,
The client just say that, "sorry i am wrong, I don't want the multiple of 5, I just want the multiple of 2", You know Which one is easier and which one is tougher to understand and change,

Quote

You said okay, whats there? At any cost I have to change the code, i need to write a function for every divisor that the client ask? because, It seems everything inside a predicate is predefined(Fixed)"

Well now you have a question, is everything inside a predicate is fixed?
My answer is no you can tweak it
I have given an example of how you can use it
See the below class
```Public Class MyIntegerFinder

Private _Divisor As Integer
Public Property Divisor As Integer
Get
Return _Divisor
End Get
Set(value As Integer)
_Divisor = value
End Set
End Property

Public Function MultipleofDivisor(ByVal i As Integer) As Boolean
Return i Mod Divisor = 0
End Function

Public Function MultipleofDivisorWithoutZero(ByVal i As Integer) As Boolean
Return (i Mod Divisor = 0) and i <>0
End Function

End Class

```

Now you can use this class as your divisor class like this
```Dim c As New MyIntegerFinder
c.Divisor = CInt(TextBox1.Text)