# Extract all elements from a list that belong to a set or have a set element as an argument

EDIT: Added that I want to extract not only the variables from a specific set, but also functions involving variables from a specific set.

Given the set

S = [s1, s2, s3]


and some vector of values

x = {1, 2, 4, s1, y, f1[s1], f2[s2]}


I want to pick out all values in x that belong to the set S, and also all functions involving arguments with from the set S. Maybe some approach like

Smash[x_] := Cases[{x}, _, {0, Infinity}] (*Eq. Smash[f1[s1]] = {f1[s1],s1})
Select[x, IntersectingQ[Smash[#], S] ]


But it really doesn't work. I guess it's an issue regarding the syntax mainly, I don't really know what do with #. How can I solve this? Any answers explaining the syntax issue or giving alternative solutions will be greatly appreciated.

-
(i) you should change square brackets in assignment of S (ii) avoid capital letters to avoid conflicts with MMA built-ins (iii)why not use Intersection[S,x].(iv) to make you own code work just put an & at the end of your criterion – ubpdqn Feb 27 at 11:57
Welcome to Mathematica.StackExchange Martin. I attempted to address your needs in an answer below. Nevertheless this question will probably be closed as "easily found in the documentation." I know the documentation can be opaque at times. Consider possibly also making use of these resources: mathprogramming-intro.org and (18393) as well as the links in the Introduction section of (18). – Mr.Wizard Feb 27 at 12:00
ubpdqn: Thy! Just tried Select[x, IntersectingQ[Smash[#], S] &] but it gives me Tag Slot in #1 is Protected. – Martin Feb 27 at 12:57

What I think you want:

S = {s1, s2, s3};

x = {1, 2, 4, s1, y};

Intersection[x, S]


Outputs: {s1}

As for # see http://reference.wolfram.com/language/tutorial/PureFunctions.html

set = {s1, s2, s3};
x = {1, 2, 4, s1, y, f1[s1], f2[s2]}

p = Alternatives @@ set;

Cases[x, p | _[p]]

{s1, f1[s1], f2[s2]}


Reference Alternatives.

set = {s1, s2, s3};
x = {1, 2, f1[s1 + s2] , f2[f1[s1] + s3], 4, f3[s1 + q], s1, y, f1[s1], f2[s2]}

p = Alternatives @@ set;

Select[x, Not@*FreeQ[p]]

{f1[s1 + s2], f2[s3 + f1[s1]], f3[q + s1], s1, f1[s1], f2[s2]}


Reference FreeQ and Composition.

If however you wish to exclude f3[q + s1] because of q you will need to look at the leaves of the expression, but not heads:

Select[x, FreeQ[#, Except[p], {-1}, Heads -> False] &]

{f1[s1 + s2], f2[s3 + f1[s1]], s1, f1[s1], f2[s2]}


Reference: Levels: how do they work?

-
did you think my comment was terse or discourteous? I did not mean it that way. – ubpdqn Feb 27 at 12:24
@ubpdqn Are you asking me that because I also posted a comment? I was writing it before yours appeared. I see no problem with your comment. In fact you mentioned that user symbols starting with Capital Letters is a bad idea, which is something I forgot. – Mr.Wizard Feb 27 at 12:52
No it was a great answer! However, I just realised that the question is a bit more extensive than I first thought. I updated the original post. – Martin Feb 27 at 12:53
@Mr.Wizard I think I felt guilty for not sating welcome or putting a format welcome message. I just thought it could be resolved quickly. – ubpdqn Feb 27 at 12:54
Neat, really neat! Tried to upvote your answer but I don't have reputation enough to do it. Thank you! – Martin Feb 27 at 13:08

It is not completely clear to me what form the output is intended to take. Recommend that you always give examples of both inputs and corresponding outputs.

S = {s1, s2, s3};

x = {1, 2, 4, s1, y, f1[s1], f2[s2], f1[s1 + s2], f2[f1[s1] + s3]};

DeleteCases[x, _?(FreeQ[#, Alternatives @@ S] &)]

(*  {s1, f1[s1], f2[s2], f1[s1 + s2], f2[s3 + f1[s1]]}  *)

-