4
$\begingroup$

I have the following dataset

data = {{"one", "two", "three", "a", "b", "c"}, {"four", "five", "d"}}

I want to delete all the strings with length < 2. The desired output is:

{{"one", "two", "three"}, {"four", "five"}}

I found several solutions on this site like:

DeleteCases[#, x_ /; Length[x] < 2] & /@ data

But none of them resulted in my desired output. Any suggestion?

$\endgroup$
2
  • 1
    $\begingroup$ Cases[#, x_ /; StringLength[x] >= 2] & /@ data $\endgroup$
    – garej
    Jun 1, 2017 at 5:32
  • 1
    $\begingroup$ Tangentially related: (8945). $\endgroup$ Jun 1, 2017 at 18:23

5 Answers 5

9
$\begingroup$

many ways to do that..

DeleteCases[#, s_String /; StringLength[s] < 2] & /@ data
DeleteCases[data, s_String /; StringLength[s] < 2, {2}]
Select[#, StringLength[#] > 1 &] & /@ data
data /. s_String /; StringLength[s] < 2 :> Sequence @@ {}
$\endgroup$
6
  • $\begingroup$ OP asked for <2 or if you use select >=2. Please correct your answer $\endgroup$
    – ZaMoC
    May 31, 2017 at 20:33
  • $\begingroup$ @Jenny_mathy length must be an integer so >1 and >=2 are equivalent. $\endgroup$
    – george2079
    May 31, 2017 at 20:40
  • 1
    $\begingroup$ yes of course. any of those two. >2 was wrong $\endgroup$
    – ZaMoC
    May 31, 2017 at 20:43
  • 4
    $\begingroup$ RuleDelayed has the SequenceHold attribute, so your last version could have been just data /. s_String /; StringLength[s] < 2 -> Sequence[]. In M10.2+ you could also use Nothing instead of Sequence[]. $\endgroup$
    – Carl Woll
    Jun 1, 2017 at 0:57
  • 4
    $\begingroup$ Also, you could use a level spec of {-1} instead of {2} in your second DeleteCases example, in case the input is more deeply nested. $\endgroup$
    – Carl Woll
    Jun 1, 2017 at 0:58
3
$\begingroup$
Table[Select[data[[i]], StringLength@# >= 2 &], {i, Length@data}]
$\endgroup$
3
$\begingroup$
Pick[#, UnitStep[StringLength@# - #2], 1] &[data, 2] (*thanks: @AlexeyPopkov*)

{{"one", "two", "three"}, {"four", "five"}}

$\endgroup$
2
  • 3
    $\begingroup$ Note that StringLength is Listable, so your solution can be simplified to Pick[#, UnitStep[StringLength@# - #2], 1] &[data, 2]. $\endgroup$ Jun 1, 2017 at 4:31
  • $\begingroup$ Great point, thank you @Alexey. $\endgroup$
    – kglr
    Jun 1, 2017 at 11:10
1
$\begingroup$
data = {{"one", "two", "three", "a", "b", "c"}, {"four", "five", "d"}}
data // Map[StringLength@# >= 2 &, #, {-1}] & // Pick[data, #] & (*{2}->{-1}*)
$\endgroup$
1
  • 1
    $\begingroup$ With third argument of Map being {-1} instead of {2} your solution generalizes to arbitrary deeply nested lists of strings. $\endgroup$ Jun 1, 2017 at 17:54
0
$\begingroup$
Map[Cases[__?(StringLength[#] >= 2 &)]][data]
Map[Cases[x__/;StringLength[x] >= 2]][data]
$\endgroup$
2
  • $\begingroup$ The OP asked for removing <2, so you should use >=2. $\endgroup$ Jun 1, 2017 at 17:49
  • $\begingroup$ @AlexeyPopkov thanks. forgot to double check it $\endgroup$
    – Ali Hashmi
    Jun 1, 2017 at 17:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.