Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Consider the following:


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

7 Answers 7

up vote 11 down vote accepted

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]


 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*"] &)]]

A possibly dangerous version that works for your example:

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

uh, and adding variety to the Pick faction:

Pick[data, Thread[StringTake[data, 1] != "A"]]
+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"} *)

This site is currently not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .