Omis
Omis

Reputation: 31

How to check if an value matches all conditions

I want to make a function that checks if a value matches all conditions that are Listed somewhere. I've been thinking how to do it with delegates, but nothing came into my mind. Because I dont know how to check if every function in delegate returns true. Here's code I tried. it gives me method name expected error.

public List<bool> conditionsToCheck;
    public bool isWordValid(string wordToCheck)
    {
        bool[] checkResults = new bool[conditionsToCheck.Count];
        for (int i = 0; i < conditionsToCheck.Count; i++)
        {
            checkResults[i] = conditionsToCheck[i](wordToCheck);
        }
        //then I check if all bool values in checkResults contain true
    }
    public void AddConditionToCheck(bool condition)
        {
            conditionsToCheck.Add(condition);
        }

Thank you in advance!

Upvotes: 1

Views: 821

Answers (2)

CaTs
CaTs

Reputation: 1323

Okay lets list some conditions just for the sake of example:

public bool IsCool(string str)
{
  return str == "Cool";
}

public bool IsLong(string str)
{
  return str.Length > 100;
}

public bool IsQuestion(string str)
{
  return str.Contains("?");
}

We can group these in a collection of delegates like so:

# Required to use Func Delegate
using System;

// Func<string, bool> means a function that accepts a string parameter and returns a bool
var rules = new List<Func<string, bool>>();

// Notice we aren't doing IsCool(), we don't want to invoke the method 
// but rather pass the method itself as a parameter to Add()
rules.Add(IsCool);
rules.Add(IsLong);
rules.Add(IsQuestion);

And then check if all of the functions return true:

var str = "Bleh";
var pass = true;
foreach(var rule in rules)
  pass = pass && rule.Invoke(str);

Unneeded but cool improvements

We can use the Linq library to make it read nicer:

using System.Linq;

var pass = rules.All(rule => rule.Invoke(str));

And if we are feeling wild, add an extension method:

public static class String Extensions
{
  public static bool Satisfies(this String str, params Func<string, bool>[] rules)
  {
    return rules.All(rule => rule.Invoke(str);
  }
}

"Woah!".Satisfies(IsLong, IsCool, IsQuestion);

Upvotes: 2

Christoph L&#252;tjen
Christoph L&#252;tjen

Reputation: 5804

Something like this?

public List<Func<string,bool>> conditionsToCheck = new();

public bool isWordValid(string wordToCheck) =>
    !conditionsToCheck.Any(c => !c(wordToCheck));

public void AddConditionToCheck(Func<string,bool> condition) =>
    conditionsToCheck.Add(condition);

The example code is not tested, but intended to show how it works.

Each condition is a function that must be evaluated later. Here's how to use it:

obj.AddConditionToCheck(w => w.Length > 4);

The isWordValid() function then calls all those conditions and stops at the first that returns false (no need to continue).

Docs:

Upvotes: 2

Related Questions