I have a series of resource objects whose properties are defined as key values. Also jobs to choose from among these resources are defined as follows.
class Resource
{
public string Name { get; set; }
public Dictionary<string, string> Properties { get; set; }
}
class Job
{
public string Name { get; set; }
public List<KeyValueOperator> Properties { get; set; }
}
class KeyValueOperator
{
public string Key { get; set; }
public string Value { get; set; }
public EnumOperator Operator { get; set; }
}
enum EnumOperator
{
Equals = 0,
LessThan = 1,
LessThanEqual = 2,
GreaterThan = 3,
GreaterThanEqual = 4
}
void Main()
{
System.Collections.Generic.List<Resource> resources = new List<UserQuery.Resource>();
var res1 = new Resource { Name = "Res1", Properties = new Dictionary<string, string>() };
res1.Properties.Add("color", "red");
res1.Properties.Add("size", "small");
res1.Properties.Add("age", "3");
res1.Properties.Add("speed", "10");
resources.Add(res1);
var res2 = new Resource { Name = "Res2", Properties = new Dictionary<string, string>() };
res2.Properties.Add("color", "blue");
res2.Properties.Add("size", "small");
res2.Properties.Add("age", "4");
res2.Properties.Add("speed", "8");
resources.Add(res2);
var res3 = new Resource { Name = "Res3", Properties = new Dictionary<string, string>() };
res3.Properties.Add("color", "red");
res3.Properties.Add("size", "large");
res3.Properties.Add("age", "10");
res3.Properties.Add("speed", "5");
resources.Add(res2);
System.Collections.Generic.List<KeyValueOperator> jobProps = new List<UserQuery.KeyValueOperator>();
jobProps.Add(new KeyValueOperator { Key = "color", Value = "red", Operator = EnumOperator.Equals });
jobProps.Add(new KeyValueOperator { Key = "size", Value = "small", Operator = EnumOperator.Equals });
jobProps.Add(new KeyValueOperator { Key = "age", Value = "2", Operator = EnumOperator.LessThanEqual });
Job job1 = new Job { Name = "job1", Properties = jobProps };
}
In case of checking only equality from the key value list, the following code fragment works.
var filtered = resources
.Where(x => job1.Properties
.All(y => x.Properties
.Any(r => r.Key == y.Key && r.Value == y.Value)))
.ToList();
I want to filter not only with equality, but also with operators defined as EnumOperator. Is there a library that can do this? Or how can I do?
One simple way to accomplish this is using the CompareTo()
method. You can create an extension method for EnumOperator
that implements the logic for each operator:
static class EnumOperatorExtensions
{
public static bool Execute(this EnumOperator @operator, string left, string right)
{
int comparison = left.CompareTo(right);
return @operator switch
{
EnumOperator.Equals => comparison == 0,
EnumOperator.LessThanEqual => comparison <= 0,
EnumOperator.LessThan => comparison < 0,
EnumOperator.GreaterThanEqual => comparison >= 0,
EnumOperator.GreaterThan => comparison > 0,
_ => throw new NotImplementedException()
};
}
}
And then your usage of it would look like:
List<Resource> filtered = resources
.Where(x => job1.Properties
.All(y => x.Properties
.Any(r => r.Key == y.Key && y.Operator.Execute(y.Value, r.Value))))
.ToList();
Using the setup you provided, this gives the following results:
[
{
"Name": "Res1",
"Properties": {
"color": "red",
"size": "small",
"age": "3",
"speed": "10"
}
}
]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.