Building a list of products from the elements in another list

You can use GroupBy in several ways:

GroupBy[list, Head, Apply[Times]] /@ {Symbol, Integer, Real}

{x y z, 12, -67.7251}

or using a combination of GroupBy andLookup (thanks: CarlWoll):

Lookup[{Symbol, Integer, Real}] @ GroupBy[list, Head, Apply[Times]] 

same result

RotateRight @ Values @ GroupBy[SortBy[Head] @ list, Head, Apply[Times]] 

same result

Alternatively, you can use GatherBy:

RotateRight[Times @@@ GatherBy[SortBy[Head] @ list, Head]]

{x y z, 12, -67.7251}

Also, Replace:

Times @@@ Replace[list, {Except @ Blank @ # -> 1} & /@ {Symbol, Integer, Real}, {1}]

and DeleteCases:

Times @@@ (DeleteCases[list, Except@Blank@#] & /@ {Symbol, Integer, Real})

This doesn't involve any rules, but you could use Cases to select the desired types, using Through and Times as needed:

Times@@@Through@{Cases[_Symbol], Cases[_Integer], Cases[_Real]}@list

{x y z, 12, -67.7251}


A way of doing it with Reap and Sow that would work in versions as old as V5, long before newfangled functions like GroupBy were introduced (V.10).

list = {x, 3.2, y, 1, 2.679, 3, z, 4, -7.9};
Reap[
  Switch[#,
     _Symbol, Sow[#, "s"],
     _Integer, Sow[#, "i"],
     _Real, Sow[#, "r"]] & /@ list,
  {"s", "i", "r"}, 
  Times @@ #2&][[-1, All, 1]]
{x y z, 12, -67.7251}