Update 2017
Mathematica 10 introduced MaximalBy
, becoming the canonical method.
MaximalBy[{{1, 2, 3}, {10}, {6, 2}, {3, 7}}, Total]
{{10}, {3, 7}}
It is fast as shown in the updated timings below.
If I understand the question this should be fastest:
listMaxArg[f_, L_List] := L ~Extract~ Ordering[f /@ L, -1]
listMaxArg[Total, {{1, 2, 3}, {10}}]
{10}
You could also find the top n
values by using -n
as the second argument to Ordering
.
This could be included in the function, e.g. listMaxArg[f_, L_List, n_Integer] := . . .
This method should be fast for finding multiple maximum values:
listMaxArg[f_, L_List] := L ~Extract~ Position[#, Max@#] &[f /@ L]
listMaxArg[Total, {{1, 2, 3}, {10}, {6, 2}, {3, 7}}]
{{10}, {3, 7}}
I argue the superiority of the Extract
-Position
method (from Arnoud Buzing) over Select
on the basis of timings. I will use Tr
in the place of Total
as it is faster on Packed Arrays, and therefore better shows the overhead of each method.
listMaxArgRM[f_, list_] :=
With[{max = f /@ list // Max}, Select[list, f@# == max &]]
listMaxArgMrW[f_, L_List] :=
L ~Extract~ Position[#, Max@#] &[f /@ L]
SeedRandom[1]
list = RandomInteger[7, #] & /@ RandomInteger[{1, 5}, 1000000];
r1 = listMaxArgRM[Tr, list]; // RepeatedTiming
r2 = listMaxArgMrW[Tr, list]; // RepeatedTiming
r3 = MaximalBy[list, Tr]; // RepeatedTiming
r1 === r2 === r3
{0.77, Null}
{0.219, Null}
{0.191, Null}
True