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 '17 at 5:32
  • 1
    $\begingroup$ Tangentially related: (8945). $\endgroup$ Jun 1 '17 at 18:23
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 '17 at 20:33
  • $\begingroup$ @Jenny_mathy length must be an integer so >1 and >=2 are equivalent. $\endgroup$
    – george2079
    May 31 '17 at 20:40
  • 1
    $\begingroup$ yes of course. any of those two. >2 was wrong $\endgroup$
    – ZaMoC
    May 31 '17 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 '17 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 '17 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 '17 at 4:31
  • $\begingroup$ Great point, thank you @Alexey. $\endgroup$
    – kglr
    Jun 1 '17 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 '17 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 '17 at 17:49
  • $\begingroup$ @AlexeyPopkov thanks. forgot to double check it $\endgroup$
    – Ali Hashmi
    Jun 1 '17 at 17:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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