# DeleteCases on list of Strings

Consider the following:

data={"AB","CD","AF"};


Now I would like to delete all String from data which starts with "A".

Result: {"CD"}

-
 May be somthing like DeleteDuplicates[data,First@Characters[#]=="A"] but abviously this is not working. – John Apr 19 '12 at 15:07

I am not sure how to do this using DeleteCases, but you can still use the Select function:

Select[data, StringTake[#, 1] != "A" &]


which has the desired result.

Edit Actually, you can also use DeleteCases like this:

DeleteCases[data, _?(StringTake[#, 1] == "A" &)]

-

Here is another one:

DeleteCases[data, _?(StringMatchQ[#, "A*"] &)]

-
The OP should take careful note of the parentheses around StringMatchQ[#, "A*"]& as the parser for PatternTest (?) is aggressive. Without it, the parser comes up with Function[PatternTest[Blank[], StringMatchQ][Slot[1], "A*"]] as opposed to the correct form PatternTest[Blank[], Function[StringMatchQ[Slot[1], "A*"]]]. – rcollyer Apr 19 '12 at 15:21
I don't want to post it as a new answer, as there are already quite a handful, and it is very similar to the one above but uses Condition instead of PatternTest: DeleteCases[data, x_ /; StringMatchQ[x, "A*"]]. And of course there are a million ways to write the same pattern differently. – István Zachar Apr 19 '12 at 17:20
 Pick[data, StringMatchQ[#, "A*"] & /@ data, False]
(* => {"CD"} *)


EDIT: As noted in YvesKlett's comment, since StringMatchQ threads over its first argument, we can also use

 Pick[data, StringMatchQ[data, "A*"], False]


or

 Pick[#, StringMatchQ[#, "A*"], False]&@data

-
The disadvantage I can see is the double pass over data. But, it works, so +1. – rcollyer Apr 19 '12 at 15:24
Pick[data, StringMatchQ[data, "A*"], False] should work as well, since it accepts a list of strings as first argument... saves on wear and tear on your keyboard ;-) – Yves Klett Apr 19 '12 at 16:01
@YvesKlett, right! Thank you. – kguler Apr 19 '12 at 16:36
@rcollyer, thanks for the vote. For large lists, Pick "usually" more than compensates for the double-pass overhead associated with creation of the selector array, provided, of course, the selector array is carefully constructed. – kguler Apr 19 '12 at 17:00

Another method using Select but with what I find to be a more obvious notation.

Select[d, StringMatchQ[#, Except["A"] ~~ __] &]

-
Cases[data, Except[_?(StringMatchQ[#, "A*"] &)]]

{"CD"}

-

A possibly dangerous version that works for your example:

data = {"AB", "CD", "AF"};
Flatten[StringCases[data, Except["A"] ~~ __]]

{"CD"}


uh, and adding variety to the Pick faction:

Pick[data, Thread[StringTake[data, 1] != "A"]]

{"CD"}

-
 +1 for posting the dangerous version. I came up with that one as well, and thought, "I don't like the look of this" – tkott Apr 19 '12 at 16:27 Sometimes you gotta take a risk ;-) – Yves Klett Apr 19 '12 at 16:47 Can you elucidate why the first one is dangerous? – rcollyer Apr 19 '12 at 17:02 I didn't test but you might get tangled up with other string configurations more easily? – Yves Klett Apr 19 '12 at 17:24

Here's yet another solution that has not been mentioned using Select and StringFreeQ

Select[{"AB", "CD", "AF"}, StringFreeQ[#, "A" ~~ ___] &]
(* {"CD"} *)

-