# Extract the first element in the list when second element is minimal

There is a list in the form {a,b}, where the list is the numerical solution of some equation; List=Table[z[i]]. I need the "a" when "b" is minimal in the list.

• What do you mean by minimal ? Can you give us a simple example with a list and what you want ? May 18, 2017 at 15:04
• SortBy[list, Last][[1,1]]
– nben
May 18, 2017 at 15:17

Have you seen MinimalBy?

SeedRandom
v = RandomInteger[99, {7, 2}]

MinimalBy[v, Last]

{{92, 57}, {22, 84}, {63, 1}, {81, 96}, {19, 38}, {67, 68}, {63, 39}}

{{63, 1}}


First, I would like to say that MinimalBy (in the answers by @Mr. Wizard/@UnchartedWorks) is the cleanest way to solve the problem. It's too bad it's not optimized for arrays.

A small adjustment @MikeY's use of Ordering results in a tremendous performance improvement. I made a reference to it in a comment, but it seems it has not been appreciated in the way I expected. So I will demonstrate. Ordering[x, 1] is a special, optimized case that returns the position of the minimal element in x.

SeedRandom
v = RandomInteger[10^9, {10^7, 2}];

v[[v[[All, 2]] ~Ordering~ 1]] // AbsoluteTiming
MinimalBy[v, Last] // AbsoluteTiming                    (* Mr. Wizard, UnchartedWorks)
v[[Ordering[v[[All, 2]]] // First]] // AbsoluteTiming   (* another tweak of MikeY's *)
v[[Ordering[v[[All, 2]]]]] // First // AbsoluteTiming   (* MikeY *)
(*
{0.188194, {{497087695, 12}}}
{0.452981, {{497087695, 12}}}
{2.19028, {497087695, 12}}
{2.52904, {497087695, 12}}
*)


Note: Ordering[x, -1] is also a special optimized case that returns the position of the maximal element of x. Other cases of Ordering compute the complete ordering, which takes considerably longer. Ordering has been used in these ways in many answers on the site.

Ordering[v[[All, 2]], 1] // AbsoluteTiming        (* min position *)
Ordering[v[[All, 2]], -1] // AbsoluteTiming       (* max position *)
Ordering[v[[All, 2]]] // First // AbsoluteTiming  (* min position from complete ordering *)
Ordering[v[[All, 2]], {2}] // AbsoluteTiming      (* 2nd smallest position *)
Ordering[v[[All, 2]], 2] // AbsoluteTiming        (* two smallest positions *)
(*
{0.188538, {8647676}}
{0.194112, {323408}}
{2.15685, 8647676}
{2.16561, {8296548}}
{2.16896, {8647676, 8296548}}
*)


 lst = Table[RandomInteger[100, 2], {10}]


lst={{24, 100}, {2, 30}, {93, 26}, {37, 86}, {66, 71}, {92, 27}, {94, 25}, {16, 39}, {30, 68}, {65, 98}}

Pick off the element you want by ordering the list based on second column

lst[[Ordering[lst[[All, 2]]]]] // First


{94, 25}

Pick off just element 'a'

    lst[[Ordering[lst[[All, 2]]]]] // First// First


94

• Have you seen the form Ordering[lst[[All, 2]], 1]? May 18, 2017 at 16:02
• @Michael E2, definitely more terse May 18, 2017 at 16:33
• And faster when put inside lst[[..]] -- no reordering of the list. May 18, 2017 at 18:58

In:

SeedRandom;
xss = Table[RandomInteger[100, 2], {10}]
First @@ MinimalBy[xss, Last]


Out:

{{80, 14}, {0, 67}, {3, 65}, {100, 23}, {97, 68}, {74, 15}, {24,
4}, {100, 90}, {83, 70}, {1, 30}}
24

SeedRandom;
v = RandomInteger[99, {7, 2}];

First@SortBy[v, Last]
(* {63, 1} *)


also

Extract[#, Position[#[[All, 2]], Min[#[[All, 2]]]]] &@v