版本: Unity 6 (6000.0)
语言English
  • C#

QueryFilterOperator.AddHandler

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交内容,但我们确实阅读了用户提出的每个建议更改,并在适用情况下进行更新。

关闭

提交失败

由于某些原因,您的建议更改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

声明

public Search.QueryFilterOperator AddHandler(Func<TFilterVariable,TFilterConstant,bool> handler);

声明

public Search.QueryFilterOperator AddHandler(Func<TFilterVariable,TFilterConstant,stringComparison,bool> handler);

参数

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})";
        }
    }
}