QueryFilterOperator.AddHandler
Declaration
public Search.QueryFilterOperator AddHandler(Func<TFilterVariable,TFilterConstant,bool> handler);public Search.QueryFilterOperator AddHandler(Func<TFilterVariable,TFilterConstant,stringComparison,bool> handler);Параметры
| Параметр | Описание |
|---|---|
| обработчик | Обратный вызов для обработки операции. Принимает TFilterVariable (значение, возвращаемое обработчиком фильтров, оно будет различаться для каждого элемента), TFilterConstant (правое значение оператора, которое является постоянным), и опцию StringComparison и возвращает логическое значение, указывающее, проходит ли фильтр или нет. |
Возвращаемое значение
QueryFilterOperator Текущий QueryFilterOperator.
Описание
Добавление пользовательского обработчика оператора фильтра.
<TFilterVariable>: Тип левого операнда оператора. Это тип, возвращаемый обработчиком фильтров.
<TFilterConstant>: Тип правого операнда оператора.
Обработчик операторов — это функция, которая выполняется для определенного оператора (например, "=") с определенными требованиями к типу. Обработчик операторов выбирается по возвращаемому значению обработчика фильтров (см. AddFilter), которое идентифицируется при анализе запроса, и типу значения фильтра.
// Add a new modulo operator on this filter
var op = "%";
queryEngine.TryGetFilter("id", out var filter);
filter.AddOperator(op)
.AddHandler((int ev, int fv) => ev % fv == 0)
.AddHandler((float ev, float fv) => Math.Abs(ev % fv) < 0.00000001f);
Ниже пример, в котором мы переопределяем поведение оператора «=» для всех фильтров при работе со строками: вместо обычного сравнения выполняется поиск по регулярному выражению.
using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using UnityEditor; using UnityEditor.Search; using UnityEngine; static class Example_QueryEngine_RegexValue { static QueryEngine<MyObjectType> SetupQueryEngine() { var queryEngine = new QueryEngine<MyObjectType>(); queryEngine.AddFilter("id", myObj => myObj.id); queryEngine.AddFilter("n", myObj => myObj.name); queryEngine.SetSearchDataCallback(myObj => new[] { myObj.id.ToString(), myObj.name }); // Override the = operators to do a regex match var op = queryEngine.GetOperator("="); op.AddHandler((string ev, string fv) => RegexMatch(fv, ev)); return queryEngine; } static bool RegexMatch(string pattern, string source) { var match = Regex.Match(source, pattern); return match.Success; } static string[] s_Words = new[] { "bob", "cat", "car", "happy", "sad", "squirrel", "pizza", "dog", "over", "bing", "bong" }; static IEnumerable<MyObjectType> GenerateData(int count) { for (var i = 0; i < count; ++i) { var wordCount = Random.Range(1, 6); var words = new List<string>(); for (var j = 0; j < wordCount; ++j) words.Add(s_Words[Random.Range(0, s_Words.Length)]); var name = string.Join(" ", words); var id = $"{Random.Range(0, 1000)}-{s_Words[Random.Range(0, s_Words.Length)]}"; yield return new MyObjectType() { id = id, name = name }; } } static void FilterData(string text, QueryEngine<MyObjectType> queryEngine, IEnumerable<MyObjectType> data) { var query = queryEngine.ParseQuery(text); if (!query.valid) { foreach (var queryError in query.errors) Debug.LogFormat(LogType.Error, LogOption.NoStacktrace, null, $"Error parsing query at position {queryError.index}: {queryError.reason}"); return; } var filteredData = query.Apply(data).ToList(); var escapedText = text.Replace("{", "{{").Replace("}", "}}"); Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, $"Query \"{escapedText}\" yielded {filteredData.Count} result{(filteredData.Count > 1 ? "s" : "")}"); foreach (var filteredObject in filteredData) Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, filteredObject.ToString()); } [MenuItem("Examples/QueryEngine/RegexValue")] public static void RunExample() { // Set up the query engine var queryEngine = SetupQueryEngine(); var data = GenerateData(100); // Find all items with an id that match "^\\d{2}-c.+" (for example, "42-cat" or "99-car") // The quotes are required when using special characters like {}. FilterData("id=\"^\\d{2}-c.+\"", queryEngine, data); // Find all items with a name containing a duplicate (for example, "squirrel cat cat dog" or "pizza pizza dog") // The quotes are required when using special characters like {}. FilterData("n=(\\S+)\\s+(\\1)", queryEngine, data); } class MyObjectType { public string id { get; set; } public string name { get; set; } = string.Empty; public override string ToString() { return $"({id}, {name})"; } } }