Code: Select all
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();
Meine Idee, dieses Problem zu lösen, beruht auf der Tatsache, dass jeder Ordner meist Dateien enthält, die einem bestimmten Muster entsprechen. Wenn ich also mit dem Abgleich mit dem Muster beginne, das mit der vorherigen Datei übereinstimmt, ist die Wahrscheinlichkeit groß, dass es auch mit demselben Muster abgeglichen wird (oder mit keinem Muster übereinstimmt). Anstatt meine regulären Ausdrücke in einem Standardarray zu platzieren, denke ich darüber nach, sie in eine MRU-Struktur (Most Latest Used) einzufügen, die ihren Inhalt nach jedem erfolgreichen Any LINQ-Vorgang aktiv neu anordnet. Wenn es mir gelingt, diese Struktur zu implementieren, muss ich in meinem Code nur die Definition der regulären Ausdrücke ändern:
Code: Select all
MruArray regexes = new(new(@"^[a-f]+$"), new(@"^[g-l]+$"), ...
Code: Select all
class MruArray : IEnumerable
{
public MruArray(params T[] items);
public IEnumerator GetEnumerator();
}
Code: Select all
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));
Code: Select all
5, 1, 2, 3, 4, 6, 7, 8
3, 5, 1, 2, 4, 6, 7, 8
8, 3, 5, 1, 2, 4, 6, 7
- Wenn Any eine Übereinstimmung in der Sequenz findet, sollte das letzte aufgezählte Element an erster Stelle stehen.
- Wenn Any die gesamte Sequenz auflistet, ohne eine Übereinstimmung zu finden, sollte die Sequenz unverändert bleiben.
Thread-Sicherheit ist unerwünscht. Die Struktur sollte für Multithreading ohne Synchronisierung nicht sicher sein.
Hinweis: Der Schwerpunkt der Frage liegt auf der Implementierung der MRU-Datenstruktur, nicht auf anderen Ideen zur Beschleunigung der Suche im Ordner.
Bearbeiten: Ich habe oben eine vereinfachte Version meines Problems vorgestellt. In Wirklichkeit bin ich nicht nur an den Dateien interessiert, die dem Muster entsprechen. Ich interessiere mich für Unterausdrücke innerhalb der Muster und gruppiere dann die Dateien basierend auf diesen Unterausdrücken. Mein eigentlicher Code sieht also eher so aus:
Code: Select all
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();
Mobile version