2016-06-03 3 views
2

Im совершенно новый для C#, поэтому попытка протестировать простой строковый фильтр, но не получить желаемые результаты. Это мой метод испытания:Возврат списка, отфильтрованного на основе другого списка в C#

[TestMethod] 
    public void Test_ExceptFilter() 
    { 
     IEnumerable<string> allnames = new List<string>(){"Thumbs.db","~","one","two exe here","three"}; 
     var u = FileLister.GetFilteredList(allnames, new [] { "thumbs","~"}, false); 
    } 

У меня есть статический класс с именем FileLister, который имеет метод GetFilteredList, и бит, который не работает, когда я пытаюсь вернуть список, который не содержит никаких строки, которые находятся во втором IEnumerable.

Так что в моем примере здесь я ожидаю, что var u будет иметь «один», «два exe здесь» и «три», но в нем есть все элементы из списка allnames !.

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

//Return strings that contain or dont contain any element in the array 
    public static IEnumerable<string> GetFilteredList(IEnumerable<string> myfiles, 
     IEnumerable<string> filterbythesewords, bool includewords) 
    { 
     if (includewords) 
     { 
      return from line in myfiles 
       where filterbythesewords.Any(item => line.Contains(item)) 
       select line; 
     } 
     else 
     { 

      return from line in myfiles 
       where filterbythesewords.Any(item => !line.Contains(item)) 
       select line; 


     } 
    } 

ВТОРОЙ СУДЕБНОГО

//Return strings that contain or dont contain any element in the array 
    public static IEnumerable<string> GetFilteredList(IEnumerable<string> myfiles, 
     IEnumerable<string> filterbythesewords, bool includewords) 
    { 
     if (includewords) 
     { 
      return from line in myfiles 
       where filterbythesewords.Any(item => line.Contains(item)) 
       select line; 
     } 
     else 
     { 

      List<string> p = new List<string>(); 
      p.AddRange(myfiles.Except(filterbythesewords)); 
      return p; 


     } 
    } 

ТРЕТИЙ СУД

//Return strings that contain or dont contain any element in the array 
    public static IEnumerable<string> GetFilteredList(IEnumerable<string> myfiles, 
     IEnumerable<string> filterbythesewords, bool includewords) 
    { 
     if (includewords) 
     { 
      return from line in myfiles 
       where filterbythesewords.Any(item => line.Contains(item)) 
       select line; 
     } 
     else 
     { 
      return myfiles.Where(file => filterbythesewords.Any(x => !file.ToUpperInvariant().Contains(x.ToUpperInvariant()))); 
     } 
    } 

Как я могу сделать эту работу, пожалуйста? В конечном счете, я хочу, чтобы иметь возможность фильтровать имена файлов из списка каталогов на основе их расширений файлов или части их имен.

веселит

+1

Если вы только боретесь с половиной этого, то другая половина не имеет значения. Я предлагаю вам уменьшить свой вопрос до * только * той части, с которой у вас возникают проблемы. Чем меньше нерелевантных частей есть вопрос, тем лучше. –

+0

'return myfiles.Where (file => filterbythesewords.All (x =>! File.ToUpperInvariant(). Содержит (x.ToUpperInvariant())));' –

ответ

10

Проблема заключается в том, что вы используете Any с отрицательным условием - что означает, что вы будете включать в себя значение, если есть какие-либо слова, которые не являются включены в кандидате. Вместо этого, вы хотите думать о нем, как:

  • Исключить собой файл слова, если любое из слов которые включены в файл
  • Включите файл, если все слов не в нем.
  • Включите файл, если «не какое-либо» слов в нем (то есть, если положительная проверка не верна для всех слов)

Таким образом, вы можете использовать:

return myfiles.Where(file => filterbythesewords.All(item => !file.Contains(item)); 

или

return myfiles.Where(file => !filterbythesewords.Any(item => file.Contains(item)); 

(Там нет необходимости для выражения запроса здесь - когда вы в основном просто делаете простой фильтр, выражение запросов не помогает удобочитаемость.)

+0

'string.Contains' чувствителен к регистру –

+0

Спасибо @Jon Skeet PS: это тот же самый jon skeet, который написал C# в Depth? - получил его, чтобы выучить язык. Если это тогда спасибо и отличная книга! – Nick

+0

Моя последняя строка выглядит так: return myfiles.Where (file =>! Filterbythesewords.Any (item => file.ToUpperInvariant(). Содержит (item.ToUpperInvariant()))); ', спасибо также @Sebastian Schultz за указание, что содержит case sensitie – Nick

Смежные вопросы