12
$\begingroup$

I try to filter sublists of a list which match a pattern.

test = {{"String1", "a"}, {"String2", "b"}, {"String3", 
"a"}, {"String4", "a"}};

The result should be:

result = {{"String1", "a"}, {"String3", "a"}, {"String4", "a"}}

That means the first entry should be any String and the second should be "a".

I tried:

Select[test, (# == {_, "a"}) &]

Which evaluates to {}.

$\endgroup$
0

6 Answers 6

16
$\begingroup$

If you use Cases, then you can give the pattern directly

Cases[test, {_String, "a"}]

If you want to stick with Select you can do this as well but you have to transform your pattern match into a test function

Select[test, MatchQ[#, {_String, "a"}] &]
$\endgroup$
1
  • $\begingroup$ ah get it. Select needs an explicit test function. Thank you $\endgroup$
    – RMMA
    Aug 23, 2013 at 10:04
6
$\begingroup$

Another possibility:

Pick[#, (Thread@#)[[2]], "a"] &@test
{{"String1", "a"}, {"String3", "a"}, {"String4", "a"}}
$\endgroup$
5
  • 2
    $\begingroup$ being curious: why do you use Thread, instead of e.g. Pick[#, #[[All, 2]], "a"] &@test? $\endgroup$ Aug 23, 2013 at 10:11
  • $\begingroup$ Please notice that OP has said: "first entry should be any String" $\endgroup$
    – Kuba
    Aug 23, 2013 at 12:44
  • $\begingroup$ But the OP did NOT say 'any string' (note the capital). $\endgroup$
    – user1066
    Aug 23, 2013 at 12:50
  • $\begingroup$ What do you mean? I understand this as first element's head must be string, your code will accept any. $\endgroup$
    – Kuba
    Aug 23, 2013 at 19:11
  • 1
    $\begingroup$ My interpretation of the question is that the first value could be any one of "String1", "String2", "String3", "String4" (any first value). For example, what the OP tried was Select[test, (# == {_, "a"}) &]. No mention of string (lower-case) there. I know what my code does, btw. $\endgroup$
    – user1066
    Aug 23, 2013 at 19:39
2
$\begingroup$

Another solution:

Select[test, Function[{x}, StringQ[x[[1]]] && x[[2]] == "a"]]
{{"String1","a"},{"String3","a"},{"String4","a"}}
$\endgroup$
2
$\begingroup$
list = {{"String1", "a"}, {"String2", "b"}, {"String3", "a"}, {"String4", "a"}};

Pick[list, SameAs["a"] /@ Last /@ list]

{{"String1", "a"}, {"String3", "a"}, {"String4", "a"}}

SameAs came with V 13.1

$\endgroup$
2
$\begingroup$
list = {{"String1", "a"}, {"String2", "b"}, {"String3", "a"}, {"String4", "a"}};

Using ReplaceList:

ReplaceList[list, {___, s : {_String, "a"}, ___} :> s]

(*{{"String1", "a"}, {"String3", "a"}, {"String4", "a"}}*)

Or using SequenceCases:

SequenceCases[list, {s : {_String, "a"}} :> s]

(*{{"String1", "a"}, {"String3", "a"}, {"String4", "a"}}*)

Or using SequenceSplit:

(# /. Flatten@SequenceSplit[#, {{Except["a"], "a"}}] -> Nothing) &@list

(*{{"String1", "a"}, {"String3", "a"}, {"String4", "a"}}*)
$\endgroup$
1
$\begingroup$
list = {{"String1", "a"}, {"String2", "b"}, {"String3", 
    "a"}, {"String4", "a"}};

Select[list, Last@# == "a" &]
Select[EqualTo["a"]@*Last][list]
Select[IntersectingQ[{_, "a"}, #] &][list]
Pick[list, list[[All, 2]], "a"] (*taken*)
Pick[list, SameQ[Last@#, "a"] & /@ list] 
GroupBy[Last][list]["a"]
Cases[list, {s_String, "a"}]  (*taken*)
DeleteCases[list, {_String, Except["a"]}]
Extract[list, Position[list[[All, 2]], "a"]]
Replace[list, {_, Except["a"]} :> Nothing, 1]

{{"String1", "a"}, {"String3", "a"}, {"String4", "a"}}

$\endgroup$

Your Answer

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

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