0

I have a List<string> that contains some elements that have non-letter characters. For instance, I might have #232353; which doesn't contain any letter at all, or I might have SomeText,SomeOtherText and that element contains a comma, which is also not a letter. How can I remove these elements using linq? Something like this:

MyList = MyList.Where(...)

Thanks.

frenchie
  • 51,731
  • 109
  • 304
  • 510
  • See [Verifying that a string contains only letters in C#](http://stackoverflow.com/questions/1181419/verifying-that-a-string-contains-only-letters-in-c-sharp) and [How to remove elements from a generic list while iterating over it?](http://stackoverflow.com/questions/1582285/how-to-remove-elements-from-a-generic-list-while-iterating-over-it). Learn to break up your problems in smaller parts and you'll see all questions have been answered. – CodeCaster Jan 11 '14 at 12:34

2 Answers2

9

You can use Char.IsLetter to check if all characters in string are letters:

MyList = MyList.Where(s => s.All(Char.IsLetter)).ToList();
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 1
    Ok, thanks: it looks good but it's saying it can't convert an IEnumerable to a List – frenchie Jan 11 '14 at 12:31
  • @frenchie sorry, missed that thing - just add `ToList()` call to create new `List` from filtered strings – Sergey Berezovskiy Jan 11 '14 at 12:33
  • What's the "behind-the-scene" difference between your answer and Jared's answer? – frenchie Jan 11 '14 at 12:40
  • 1
    @frenchie if you need to hold filtered strings in same list, then it's better to remove them from list, instead of creating new list. If you need only enumerate result, than there is no need to modify original list or create new list. But if you need results as `List` then use Jared's option – Sergey Berezovskiy Jan 11 '14 at 12:41
4

Since this is on a List<string> you can use the RemoveAll method to remove all the values that match a specific predicate

MyList.RemoveAll(s => s.Any(c => !Char.IsLetter(c)));
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • +1 good option. Also you can use `FindAll` method of list, but that will create new list of results, as my answer does – Sergey Berezovskiy Jan 11 '14 at 12:36
  • What is the implication of saying "Since this is on a List"? – frenchie Jan 11 '14 at 12:38
  • @frenchie this means that the remove can be done in place without having to create a new collection. The `List` type has methods Add / Remove which directly modify the collection. Types like `IEnumerable` on the other hand have extension methods which are remove like but create a new collection. This means you end up with syntax like `e = e.Where(x => ...)`. – JaredPar Jan 11 '14 at 12:41
  • Ah ok, so in one case we end up with 2 lists where one is reassigned to the original reference and the other is garbage-collected while with methods that are part of the List type we only keep one list. Is that about right? – frenchie Jan 11 '14 at 12:45
  • @frenchie that is correct – JaredPar Jan 11 '14 at 12:45
  • Ok, cool; learning everyday; thanks. – frenchie Jan 11 '14 at 12:46
  • One more quick question: is a List technically a type of IEnumerable that has additional methods? – frenchie Jan 11 '14 at 12:47
  • @frenchie yes. I'd phrase it as the follownig. `List` is a type with methods and properties that implements `IEnumerable` (as well as `IList`) – JaredPar Jan 11 '14 at 12:49