LINQ Help для логической функции для списка - PullRequest
0 голосов
/ 10 июля 2010

Как создать выражение LINQ для удаления значений из одного списка, которые соответствуют критериям функции, которая возвращает логическое значение?

string[] message = "days of the week"
message.ToList().RemoveAll(c=>checkShortWord(c));

public static bool checkShortWord(string word) {
       if ((word.Length > 3) &&                        
          (!Regex.IsMatch(word, "^[0-9]+$")))          
        return true;

      return false;
}

Мой конечный массив строк теперь должен быть:

message = {"days","week"}

Что я должен изменить? Мой массив сообщений никогда не меняется.

Ответы [ 4 ]

3 голосов
/ 10 июля 2010

Вы создаете новый Список и удаляете элементы из этого списка, а затем выбрасываете его. Если вам нужен массив, в котором отсутствуют удаленные элементы, вам нужно будет создать новый:

string[] message = "days of the week".Split(' ');
message = message.Where(c => checkShortWord(c)).ToArray();

В качестве альтернативы, вы можете использовать List<String> вместо string[], а затем использовать метод RemoveAll, чтобы изменить его на месте:

List<string> message = "days of the week".Split(' ').ToList();
message.RemoveAll(c => !checkShortWord(c));

Как уже упоминали другие, вы также плохо назвали свой метод предикатов. «IsLongWord» может быть более подходящим. Вы могли бы написать это немного проще, как это:

public static bool IsLongWord(string word)
{
    return word.Length > 3 && !Regex.IsMatch(word, "^[0-9]+$");
}
1 голос
/ 10 июля 2010

Предполагая, что у вас действительно есть список (IEnumerable<string>), а не неправильная message переменная, и что checkShortWord на самом деле возвращает true для коротких слов, тогда вы сделаете следующее:

IEnumerable<string> before = new [] {"days", "of", "the", "week"};
IEnumerable<string> after = before.Where(word => !checkShortWord(word)); 
1 голос
/ 10 июля 2010

Не называйте свой метод checkShortWord.Это сбивает с толку.Назовите его после того, что он действительно проверяет, например, IsShortWord.Тогда ваше лямбда-выражение будет выглядеть так:

message.ToList().RemoveAll(c => IsShortWord(c));

Другими словами, удалите всех членов списка, которые являются короткими словами.Конечно, вам также нужно присвоить свой результат переменной, если вы хотите что-то с ней сделать.

Кроме того, в вашей текущей функции ваши true и false кажутся обратными.

1 голос
/ 10 июля 2010

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

var list = message.ToList();
list.RemoveAll(word=>word.Length <= 3 || Regex.IsMatch(word, "^[0-9]+$"));

Если вы не можете изменить / исключить метод (например, вы используете его в другом месте):

var list = message.ToList();
list.RemoveAll(word=>!checkShortWord(word));
...