3
$\begingroup$

Given a function with several arguments

func[a,b,g1[x],g1[x,y],g2[1],g2[g1[1]],3]

I would like to extract all arguments with the head g1 and g2 as a list. So the output I am looking for is

{g1[x],g1[x,y],g2[1],g2[g1[1]]}

The way I used to extract one head, say g1, is simply using the rule

/.func[l___,x__g1,r___]:> {x}

However, with two heads, this method does not work. I could write a module to do that but I wonder if there is a simpler way like the above rule for one head. Thank you so much!

$\endgroup$
8
$\begingroup$

Either

takeHeads = Cases[#, _g1 | _g2] &;
func[a, b, g1[x], g1[x, y], g2[1], g2[g1[1]], 3] // takeHeads

{g1[x], g1[x, y], g2[1], g2[g1[1]]}

or define func itself as

func = Cases[{##}, _g1 | _g2] &;
func[a, b, g1[x], g1[x, y], g2[1], g2[g1[1]], 3]

{g1[x], g1[x, y], g2[1], g2[g1[1]]}

$\endgroup$
  • $\begingroup$ thank you, the method using cases is very useful. I did not know that Cases works inside the function func $\endgroup$ – mastrok Apr 17 '19 at 16:34
  • 2
    $\begingroup$ You could also use the 1-arg form of Cases, e.g. takeHeads = Cases[_g1 | _g2]. $\endgroup$ – Carl Woll Apr 17 '19 at 18:09
  • $\begingroup$ @mastrok If that surprised you that Cases worked on your custom func expression have a look at Everything is an Expression. Hope this helps to understand why this worked. $\endgroup$ – Thies Heidecke Apr 17 '19 at 18:12
  • $\begingroup$ @Thies Heidecke Yes, I know that everything is an expression. However I thought that Cases only works with List only but not a general head. Thanks! $\endgroup$ – mastrok Apr 17 '19 at 18:16
3
$\begingroup$
Select[{##&@@func[a,b,g1[x],g1[x,y],g2[1],g2[g1[1]],3]},h=#;Head@#==h&]&/@{g1,g2}    

{{g1[x], g1[x, y]}, {g2[1], g2[g1[1]]}}

$\endgroup$

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.