Код: Выделить всё
Regex[] regexes = [new(@"^[a-f]+$"), new(@"^[g-l]+$"), new(@"^[m-r]+$"), new(@"^[s-x]+$")];
string[] matchedPaths = Directory
.EnumerateFiles(@"C:\Files", "*.*", SearchOption.AllDirectories)
.Where(path =>
{
string name = Path.GetFileNameWithoutExtension(path);
return regexes.Any(regex => regex.IsMatch(name));
})
.ToArray();
Моя идея решить эту проблему связана с тем фактом, что в каждой папке обычно содержатся в основном файлы, соответствующие одному конкретному шаблону. Поэтому, если я начну сопоставлять с шаблоном, который соответствовал предыдущему файлу, есть вероятность, что он также будет соответствовать тому же шаблону (или не будет соответствовать никакому шаблону). Поэтому вместо того, чтобы помещать регулярные выражения в стандартный массив, я подумываю о том, чтобы поместить их в структуру MRU (самые недавно использованные), которая активно переупорядочивает свое содержимое после каждой успешной операции Any LINQ. Если мне удастся реализовать эту структуру, все, что мне придется изменить в своем коде, — это определение регулярных выражений:
Код: Выделить всё
MruArray regexes = new(new(@"^[a-f]+$"), new(@"^[g-l]+$"), ...
Код: Выделить всё
class MruArray : IEnumerable
{
public MruArray(params T[] items);
public IEnumerator GetEnumerator();
}
Код: Выделить всё
MruArray mru = new(1, 2, 3, 4, 5, 6, 7, 8);
_ = mru.Any(x => x == 5);
Console.WriteLine(String.Join(", ", mru));
_ = mru.Any(x => x == 3);
Console.WriteLine(String.Join(", ", mru));
_ = mru.Any(x => x == 8);
Console.WriteLine(String.Join(", ", mru));
Код: Выделить всё
5, 1, 2, 3, 4, 6, 7, 8
3, 5, 1, 2, 4, 6, 7, 8
8, 3, 5, 1, 2, 4, 6, 7
- Когда Any находит совпадение в последовательности, последний перечисляемый элемент должен стать первым.
- Когда Any перечисляет всю последовательность, не находя совпадений, последовательность должна оставаться неизменной.
Потокобезопасность нежелательна. Структура не должна быть безопасной для многопоточности без синхронизации.
Примечание: В центре внимания вопроса — реализация структуры данных MRU, а не другие идеи по ускорению поиска в папке.
Изменить: Выше я представил упрощенную версию своей проблемы. На самом деле меня интересуют не только файлы, соответствующие шаблону. Меня интересуют подвыражения внутри шаблонов, а затем группирую файлы на основе этих подвыражений. Итак, мой фактический код выглядит примерно так:
Код: Выделить всё
KeyValuePair[] groups = Directory
.EnumerateFiles(@"C:\Files", "*.*", SearchOption.AllDirectories)
.Select(p => Path.GetFileNameWithoutExtension(p))
.Select(n => regexes.Select(r => r.Match(n)).FirstOrDefault(m => m.Success))
.Where(m => m is not null)
.Select(m => m.Groups["Name"].Value)
.CountBy(x => x)
.OrderBy(p => p.Key, StringComparer.OrdinalIgnoreCase)
.ToArray();
Подробнее здесь: https://stackoverflow.com/questions/798 ... -linq-quer
Мобильная версия