C
C#2y ago
monkey

❔ Predicates

How the shit do predicates work I've been staring at a example on microsofts document on predicates for the past 5 mins and theres so much back and fourth idk what is going on, I don't know how things are getting called, I don't know how things are getting set. Please someone for the love of god explain how tf predicates work
36 Replies
monkey
monkey2y ago
They also didn't do a great job with names on the microsoft page, which is probably where the confusion of whats calling what comes from Ok actually I've managed to work out quite a bit of it but theres still one thing that confuses me because they have a method with a constructor but when they call the method they never set the constructor No idk if I'm using constructor right because microsofts examples fucking confuse me They have a method and they've got a variable in the parenthesis which never gets set when they call the method so idk how tf that example is supposed to work
Strawb 🐇
Strawb 🐇2y ago
Heya! Wave A predicate usually describes a function or method that returns a boolean value (true or false). For instance, you can use it to filter, lets say a list, for entries that match a certain condition. To make things easier to write, you can use a arrow function (Which is basically just an easy way to write a Func delegate) as a predicate, in LINQ methods for example. (This might be where some of the confusion is coming from)
var someList = new List<int>() { 1, 2, 3 };
var predicate = (int element) => element > 1;
var elementsGreaterThanOne = someList.Where(predicate).ToList();
var someList = new List<int>() { 1, 2, 3 };
var predicate = (int element) => element > 1;
var elementsGreaterThanOne = someList.Where(predicate).ToList();
You can also use the arrow function in line which makes it less cluttered:
var someList = new List<int>() { 1, 2, 3 };
var elementsGreaterThanOne = someList.Where(element => element > 1).ToList();
var someList = new List<int>() { 1, 2, 3 };
var elementsGreaterThanOne = someList.Where(element => element > 1).ToList();
monkey
monkey2y ago
I would say thank you but at this point idk if Ill understand this, so Im gonna read this and then thank you no it returns a god damn boolean god damn it so if I use (List).Find Itll just tell me if its in the list? Well more specifically (List).IndexOf or whatever
Strawb 🐇
Strawb 🐇2y ago
<IEnumerable>.Find returns the first index of an element in the collection that matches the condition of the function that you've provided
monkey
monkey2y ago
Im trying to find where the gameobject is in the list so I can remove it from the list In a simpler way then I have been that is could you say that in a bit more english? I dont understand what you mean by matches the condition of the function Really I just need a way to find stuff in a list Based on the essay your typing I assume this is going to help, so thank you
Strawb 🐇
Strawb 🐇2y ago
Alright, let's say you have a list of integers:
var someList = new List<int>() { 1, 2, 3 };
var someList = new List<int>() { 1, 2, 3 };
You'd like to get the first element in that list is greater than 2. To do that you can use a variety of methods on the collection, I'll use Find here but they all work in a similar way, through a predicate function. Basically, you pass in a function that is called for every value in the collection, if the function returns true, the condition for whatever you're trying to do is met. For First, that would mean that it returns the value:
var firstValueGreaterThanTwo = someList.First(element => element > 2);
var firstValueGreaterThanTwo = someList.First(element => element > 2);
To make this a little easier to grasp, this code would basically do the same thing:
class Example {
public void CallPredicate() {
var someList = new List<int>() { 1, 2, 3 };
int firstValueGreaterThanTwo = default;
foreach(var element in someList) {
var doesMatchPredicate = IsElementGreaterThanTwo(element);
if(doesMatchPredicate) {
firstValueGreaterThanTwo = element;
break;
}
}

Console.WriteLine($"First value in list greater than two is: {firstValueGreaterThanTwo }");
}

public bool IsElementGreaterThanTwo(int element) {
return element > 2;
}
}
class Example {
public void CallPredicate() {
var someList = new List<int>() { 1, 2, 3 };
int firstValueGreaterThanTwo = default;
foreach(var element in someList) {
var doesMatchPredicate = IsElementGreaterThanTwo(element);
if(doesMatchPredicate) {
firstValueGreaterThanTwo = element;
break;
}
}

Console.WriteLine($"First value in list greater than two is: {firstValueGreaterThanTwo }");
}

public bool IsElementGreaterThanTwo(int element) {
return element > 2;
}
}
monkey
monkey2y ago
At this point idk what I'm doing I just found .remove accepts gameobjects idk why I was fucking with predicates, thanks for the help though I'm sure it'll come in handy at some point
Strawb 🐇
Strawb 🐇2y ago
Hehe, well there are of course lots of ways you can solve that problem :p In any case though, you'll prolly at some point want to take advantage of at least one of those fancy methods taking a single or multiple predicates so it's a good thing to know about <a:neko_nod:819942443481825350>
monkey
monkey2y ago
@Michael ፡3 in the 2nd example what is element?
Strawb 🐇
Strawb 🐇2y ago
element is one entry of the list e.g. 1, then 2, then 3
monkey
monkey2y ago
oh ok, so its like when you do for(var Variable = 0; Variable < List.Count; Variable++) idk if thats just a unity thing but, it sorts through each thing in the list So element is what its currently on in the list while sorting through it?
Strawb 🐇
Strawb 🐇2y ago
Not exactly, foreach gives you the actual value of the list, not the index that you're iterating over. e.g. if it was a list of strings it'd look like this:
var names = new List<string> { "Mike", "Steve", "Monkey" };
foreach(string name in names) {
Console.WriteLine("Hi, my name is: " + name);
}

// Prints:
// Hi, my name is: Mike
// Hi, my name is: Steve
// Hi, my name is: Monkey
var names = new List<string> { "Mike", "Steve", "Monkey" };
foreach(string name in names) {
Console.WriteLine("Hi, my name is: " + name);
}

// Prints:
// Hi, my name is: Mike
// Hi, my name is: Steve
// Hi, my name is: Monkey
monkey
monkey2y ago
well i mean for does c# not have for is it only unity?
Strawb 🐇
Strawb 🐇2y ago
So it's the same as:
var names = new List<string> { "Mike", "Steve", "Monkey" };
for(var i = 0; i < names.Count, i++) {
var name = names[i];
// ...
}
var names = new List<string> { "Mike", "Steve", "Monkey" };
for(var i = 0; i < names.Count, i++) {
var name = names[i];
// ...
}
monkey
monkey2y ago
Ok, so its just a smaller version of that
Strawb 🐇
Strawb 🐇2y ago
I've never worked with unity but I'm pretty sure that you should be able to use that as think
monkey
monkey2y ago
Also is => just a if statement?
Strawb 🐇
Strawb 🐇2y ago
No, => is used as a function declaration
monkey
monkey2y ago
Oh
Strawb 🐇
Strawb 🐇2y ago
So you've got
(int parameter1, string parameter2) => { /* function body */
}
(int parameter1, string parameter2) => { /* function body */
}
and the {} on the body can be omitted if it contains a single expression e.g. someparam > 1
monkey
monkey2y ago
huh, it seems like an if statement if someparam is greater then 1 then
Strawb 🐇
Strawb 🐇2y ago
The "if statement" part happens in the body of the function in case of a predicate The parenthesis at the start define the parameters for the function, the => arrow thingy signal C# that this is a function and the { ... } after them is the body of the function Of course, then you can omit the brackets entirely, making it look more confusing
monkey
monkey2y ago
Yea Do you mind if I dm you if I ever need any more help?
Strawb 🐇
Strawb 🐇2y ago
I'm usually pretty busy with work stuff but you can always make a forum post here or use #help-0 <a:neko_nod:819942443481825350>
monkey
monkey2y ago
I was about to ask a question then remembered thats only a unity thing Alright well thanks for the help have a good day
Strawb 🐇
Strawb 🐇2y ago
No worries, you too! :3
Angius
Angius2y ago
You're thinking of >=, "greater or equal" and <= "less or equal" => is for lambda declarations, also known as anonymous functions
monkey
monkey2y ago
Well no I mean whats on the other side of that
Angius
Angius2y ago
Left side is parameters, right side is an expression
(int a, int b) => a + b;
(int a, int b) => a + b;
for example
MODiX
MODiX2y ago
Angius#1586
REPL Result: Success
var func = (int a, int b) => a + b;

func(7, 8)
var func = (int a, int b) => a + b;

func(7, 8)
Result: int
15
15
Compile: 508.299ms | Execution: 60.083ms | React with ❌ to remove this embed.
monkey
monkey2y ago
ohhh so whats on the right is what to do with whats in the parenthesis and then it returns it to the main variable
Angius
Angius2y ago
(int a, int b) => a + b;
(int a, int b) => a + b;
is about equal to a named method
public int Name(int a, int b)
{
return a + b;
}
public int Name(int a, int b)
{
return a + b;
}
The func variable in the example actually stores the method itself, not its result
monkey
monkey2y ago
Yea so the main variable is the method
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
palapapa
palapapa2y ago
Maybe you are confused because you don't know how methods like Find uses the predicate? Find basically passes each element in a list into the function that you provided, aka the predicate, and returns the first element that causes the predicate to return true. So basically:
foreach (T element in list)
{
if (predicate(element))
{
return element;
}
}
return default(T);
foreach (T element in list)
{
if (predicate(element))
{
return element;
}
}
return default(T);
default(T) is null if T is a class, or is the all-zeros value if T is a struct. You said that a predicate look like a if statement, that is because in this case it's only used to check if a element is greater than 1, but it can also do any other computation that a function can do, because a predicate is just a function. Maybe you are confused about why predicates are needed at all, and why not just an if statement. That's because sometimes you may want to do things that are more complicated than what an if statement could handle. For example you may want to send a request to a server, and then find an element in a list that has the same value as the response that the server just returned. To do this, you would need a function, a predicate, that can do this for you. As you can see, when you want a function to do a complicated thing, you might choose to pass another function to the function. In this case, you are passing another function, the predicate, to the Find function. It is called a predicate because it accepts an single argument and returns a bool. There are also other names for functions that you pass to another function, like selectors and comparators, but in essence they are all just functions that you pass to another function. As a side note, any function that you pass to another function is called a callback, so a predicate is a callback, and so are selectors and comparators. Another thing, in C#, if you want to pass a function to another function, you have to use delegates. They basically allow you to store a function in a variable. The arrow is used to define a anonymous function. There are many cases where you might want to pass a function to another function, but don't want to define a named function in you class because you are ever going to use that function once(imagine writing a whole new function every time you want to find an element in a list). In that case, the arrow notation is helpful because it allows you to define a function that has no name. In Find, you write the anonymous function directly in its argument, but you can also store the anonymous function in a delegate variable if you want to.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server
More Posts