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}