Hello. I have the following task: go through the collection of files, and carry out a filter on certain conditions. Moreover, the conditions are formed immediately before going through all the files. Now it looks like this:

foreach (string f in FileList.MainList) { // max Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚? if (max_size != 0) continue; // min Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚? if (min_size != 0) continue ; // Имя Ρ„Π°ΠΉΠ»Π° if (filenameYES!=null || filenameNO!=null) continue; // Имя ΠΏΠ°ΠΏΠΊΠΈ if (pathnameYES != null || pathnameNO != null) continue; } 

max_size, min_size, filenameYES, filenameNO and other conditions are determined BEFORE passing through all files. In order to speed up the execution of the code, I somehow need to display a pass through all the files into a separate method, and call this method only with the conditions that are defined. That is, in each file the program did not think what conditions were set, but immediately checked only the specified conditions. Please suggest how to do this.

  • There are several conditions, for example 1. Maximum file size 2. Minimum file size 3. File name contains letter A. There is a code, the result of which should be an understanding of which of each of these conditions should be checked in a loop, and which should not. After that, we loop through all the files and check the files only for those conditions that, as defined earlier, should be checked. Why it is needed - there are many conditions, there are many files. It is necessary to check exactly non-zero, let's call them so, conditions in order to speed up the processing process - Antykus

2 answers 2

It is more correct to separate the filtering logic from the bypass logic.

Deliver the creation of the predicate serving the file selection into a separate method. It will look something like this:

 Func<FileInfo, bool> CreateFilter() { List<Func<FileInfo, bool>> conditions = new List<Func<FileInfo, bool>>(); var r = new Random(); // Π½ΡƒΠΆΠ΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° if (r.Next(2) == 0) // ΠΏΡ€ΠΈ ΠΊΠ°ΠΊΠΎΠΌ-Ρ‚ΠΎ условии conditions.Add(fi => fi.Length > 15); // добавляСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π½Π° ΠΌΠΈΠ½. Π΄Π»ΠΈΠ½Ρƒ if (r.Next(2) == 0) // ΠΏΡ€ΠΈ Π΅Ρ‰Ρ‘ ΠΊΠ°ΠΊΠΎΠΌ-Ρ‚ΠΎ условии conditions.Add(fi => fi.Length < 100000); // добавляСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π½Π° макс. Π΄Π»ΠΈΠ½Ρƒ if (r.Next(3) == 2) // ΠΏΡ€ΠΈ Π΅Ρ‰Ρ‘ ΠΊΠ°ΠΊΠΎΠΌ-Ρ‚ΠΎ условии conditions.Add(fi => fi.Name.StartsWith("x")); // добавляСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π½Π° имя Ρ„Π°ΠΉΠ»Π° if (r.Next(4) == 0) // ΠΏΡ€ΠΈ Π΅Ρ‰Ρ‘ ΠΊΠ°ΠΊΠΎΠΌ-Ρ‚ΠΎ условии conditions.Add(fi => fi.Extension == ".exe"); // добавляСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π½Π° Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ // ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΡƒΠ΅ΠΌ всС условия Π² ΠΎΠ΄ΠΈΠ½ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ return fi => conditions.All(c => c(fi)); } 

And use:

 var filter = CreateFilter(); var fileInfos = files.Select(f => new FileInfo(f)).Where(filter); foreach (FileInfo fi in fileInfos) { // ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» } 

It would be possible in principle to speed up the implementation of filters by going to Expression 's, but the benefit from this is still leveled by the time it takes to access the file system.

    You can make several methods that will be taken to the input MainList. First, in the main method, you check the conditions and, depending on the condition, you call the desired method in which you already do not need to check the conditions.