# Selecting elements from lists based on string pattern

I have a list:

lis = {{"abc", 1, 2}, {"cde", 3, 4}, {"fgbc", 5, 6}}


I would like to select list items that have first elements that end in the string "bc" to give:

res = {{1,2},{5,6}}


This is a variant on this question which has to do with strings only. Thank you as always for suggestions.

Pick[lis[[All, 2 ;;]], StringEndsQ[lis[[All, 1]], "bc"]]


{{1, 2}, {5, 6}}

Also

f[{_String?(StringEndsQ["bc"]), x__}] := {x}
f[_] := Sequence[]
f /@ lis


{{1, 2}, {5, 6}}

lis = {{"abc", 1, 2}, {"cde", 3, 4}, {"fgbc", 5, 6}};


Using Cases

Cases[lis, {_?(StringTake[#, -2] == "bc" &), x_, y_} :> {x, y},
Infinity]

(* {{1, 2}, {5, 6}} *)


or

Rest /@ Cases[lis, {_?(StringTake[#, -2] == "bc" &), __}, Infinity]

(* {{1, 2}, {5, 6}} *)


Or using Select

Rest /@ Select[lis, StringTake[#[[1]], -2] == "bc" &]

(* {{1, 2}, {5, 6}} *)


Or using DeleteCases

Rest /@ DeleteCases[lis, {_?(StringTake[#, -2] != "bc" &), __},
Infinity]

(* {{1, 2}, {5, 6}} *)


This uses string matching on the first element of each sublist and then discards the first element from the matches.

lis = {{"abc", 1, 2}, {"cde", 3, 4}, {"fgbc", 5, 6}};
Rest/@Select[lis,StringMatchQ[First[#],RegularExpression["\\w*bc"]]&]

(* {{1, 2}, {5, 6}} *)


You may need to adjust the pattern given to RegularExpression if your strings do not all begin with word characters.

This works too:

If[StringEndsQ[#1, "bc"], {##2}, Nothing] & @@ # & /@ lis


since list elements that are Nothing are automatically stripped from the sequence.

• Why use (f@@ #) & /@lis instead of f@@@lis? Commented Sep 1, 2021 at 9:11
lis = {{"abc", 1, 2}, {"cde", 3, 4}, {"fgbc", 5, 6}};


Using SubsetMap:

SubsetMap[StringEndsQ[#, "bc"] &, lis, {All, 1}] //
Select[ContainsNone[{False}]] // Map[Rest]


Using Sow/Reap:

Scan[If[StringEndsQ[First@#, "bc"], Sow[Rest@#], Nothing] &, lis] //
Reap // Last // First


Result

{{1, 2}, {5, 6}}

lis = {{"abc", 1, 2}, {"cde", 3, 4}, {"fgbc", 5, 6}};

Values @ KeySelect[StringEndsQ @ "bc"] @ MapApply[# -> {##2} &] @ lis


{{1, 2}, {5, 6}}

Using Cases and StringEndsQ:

Cases[lis, {y_ /; StringEndsQ[y, "bc"], x__} :> {x}]

(*{{1, 2}, {5, 6}}*)