C # String Поиск с несколькими подстроками - PullRequest
0 голосов
/ 16 ноября 2018

Итак, я работаю над фильтром для списка ресурсов, и одним из фильтров является свойство Name (строка).

В качестве (немого) примера: имя ресурса - «Большая красная / квадратная таблица», а фильтр - «Красная таблица», это должен быть допустимый ресурс

Это то, что я мог придумать, используя немного времени, которое у меня было:

static void ApplyNameFilter(ref ApplicationViewModel model, string filter)
{
    if (string.IsNullOrEmpty(filter) || filter == "") return;
    char[] separators = {' ', ',', '.', '/', '\\', '|', '_', '-'};
    var validResources = new List<ResourceModel>();

    foreach (var resource in model.ResourcesViewModel.Resources)
    {
        var filterSubstrings =
            filter
            .ToLower()
            .Split(separators)
            .ToList();

        var resourceSubstrings =
            resource.Name
            .ToLower()
            .Split(separators)
            .ToList();

        resourceSubstrings.ForEach(substring => {
            if (filterSubstrings.Contains(substring))
                filterSubstrings.RemoveAll(sub => sub == substring);
        });

        if (filterSubstrings.Count == 0)
            validResources.Add(resource);
    }

    model.ResourcesViewModel.Resources = validResources;
}

Должен ли я использовать другой подход для этого?

EDIT: Закончилось этим, пока я не разобрался с RegEx

static void ApplyNameFilter(ref ApplicationViewModel model, string filter)
{
    if (string.IsNullOrEmpty(filter)) return;

    char[] separators = {' ', ',', '.', '/', '\\', '|', '_', '-'};
    var filterSubstrings =
        filter
            .ToLower()
            .Split(separators)
            .ToList();

    var validResources = model.ResourcesViewModel.Resources
        .Where(resource => filterSubstrings.All(fs => resource.Name.ToLower().Contains(fs)))
        .ToList();

    model.ResourcesViewModel.Resources = validResources;
}    

1 Ответ

0 голосов
/ 16 ноября 2018

Вы можете использовать LINQ, чтобы сделать это более кратким (и, возможно, более быстрым, поскольку вы создаете List s и без необходимости удаляете элементы для каждого ресурса, хотя решение, не относящееся к LINQ, может быть еще быстрее).

var validResources = model.ResourcesViewModel.Resources
                        .Where(resource => {
                            var resourceSubstrings = resource.Name.ToLower().Split(separators).ToHashSet();
                            return filterSubstrings.All(fs => resourceSubstrings.Contains(fs));
                        })
                        .ToList();

Если вы готовы принять все подстроки фильтра, находящиеся внутри Name, независимо от separators, то вы можете упростить до:

var validResources = model.ResourcesViewModel.Resources
                        .Where(resource => filterSubstrings.All(fs => resource.Name.ToLower().Contains(fs)))
                        .ToList();
...