3

I would like to select elements from list by specifying their head. E.g.

SelectWithHead[{1,2,3.5,x}, Symbol] = {x}
SelectWithHead[{1,2,3.5,x}, Real] = {3.5}

What is the simpliest way for this?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
uranix
  • 537
  • 3
  • 14

2 Answers2

7

Select[{1,2,3,5,x}, Head[#] === Symbol&] would work, but I would recommend using cases instead:

Cases[{1,2,3,5,x}, _Symbol]

{x}


One advantage of using the pattern _head is that it will not cause unwanted evaluation. To keep Head[#] === Symbol & from evaluating its argument would require rewriting it as something like Function[x, Head @ Unevaluated @ x == Symbol, HoldAll], whereas the Cases form allows this directly:

Cases[Hold[1 + 2, 3*4, 5^6], _Plus]
{3}

Although evaluation took place after the match _Plus successfully matched (only) the held expression of the form Plus[1, 2]. To return that expression also unevaluated we can use a delayed rule:

Cases[Hold[1 + 2, 3*4, 5^6], x_Plus :> Defer[x]]

{1 + 2}

(I chose Defer for this example but Hold or HoldForm may be used instead as required.)

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
nben
  • 2,148
  • 9
  • 20
0

Although most of the time I would prefer Cases there is an alternative worth mentioning: Pick.

expr = Hold[1 + 2, 3*4, 5^6];

Pick[expr, expr[[All, 0]], Plus]
Hold[1 + 2]

Part zero is used to extract the head and All represents a sequence therefore the original head Hold is retained. (See: Head and everything except Head?) Pick then finds the position(s) of literal Plus in Hold[Plus, Times, Power] and extracts the element at that position from the original Hold[1 + 2, 3*4, 5^6], again preserving the original head.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371