# Sorting a function

So I have a function f[x : {{_, _} ...}] := f /@ x; f[a_,b_]=:a+b. I can input f[{1,2},{2,0},{3,4}] and get {3,2,7}. However, I want the function to also sort out the answers so I get {{2,2},{1,3},{3,7}}, where the first value corresponds to the position of ordered pair in the input. I have no idea how to approach this. I attempted to use Sort but an error message pops up. Are there other commands that would achieve this? Thanks, I'm new to using Mathematica and any help would be appreciated!!

## 4 Answers

You can get the row sums using {2} as the second argument of Total:

Total[{{1, 2}, {2, 0}, {3, 4}}, {2}]

{3, 2, 7}


Then you can use Ordering and Sort to get the ordering of sums and the sorted sums, respectively:

Through @ {Ordering, Sort} @ %

{{2, 1, 3}, {2, 3, 7}}


and Transpose the resulting pair of lists:

Transpose @ %

{{2, 2}, {1, 3}, {3, 7}}


Combine the three steps to define a function:

ClearAll[indexedSortedSum]
indexedSortedSum = Transpose[Through@{Ordering, Sort}@Total[#, {2}]] &;

indexedSortedSum @ {{1, 2}, {2, 0}, {3, 4}}

{{2, 2}, {1, 3}, {3, 7}}


Alternatively, you can Apply Plus at Level 1 instead if using Total

ClearAll[indexedSortedSum2]
indexedSortedSum2 = Transpose[Through@{Ordering, Sort}[Plus @@@ #]] &;

indexedSortedSum2 @ {{1, 2}, {2, 0}, {3, 4}}

{{2, 2}, {1, 3}, {3, 7}}


MapIndexed work fine.

list = {{1, 2}, {2, 0}, {3, 4}};
result=SortBy[First]@MapIndexed[{Total@#1, #2} &][list]

(* {{2, {2}}, {3, {1}}, {7, {3}}} *)


and then adjust the appearance.

Flatten[#, 1] & /@ Reverse /@result

(* {{2, 2}, {1, 3}, {3, 7}} *)


Are you sure you have typed your function as you intended? I can't make it work, so I think you mean:

f[x : {{_, _} ...}] := f /@ x;
f[{a_, b_}] := a + b;

f[{{1, 2}, {2, 0}, {3, 4}}]


Which outputs

{3,2,7}


You could also use (amongst many other possibilities):

{{1, 2}, {2, 0}, {3, 4}} /. {x_, y_} -> x + y


I think from your example output {{2,2},{1,3},{3,7}} that you want to sort in ascending order of the answers, not the input tuples (but the Code Golfers will be much slicker):

list1 = {{1, 2}, {2, 0}, {3, 4}};
addByPosition[x_List] := x[[#]] /. x[[#]] -> {#, x[[#]][] + x[[#]][]} & /@ Range[Length[x]]
SortBy[Last][addByPosition[list1]]

(* {{2,2}, {1,3}, {3,7}} *)

f[list_] := (
k = 1;
Sort[Map[{k++, #[] + #[]} &, list], #1[] < #2[] &]
)

f[{{1, 2}, {2, 0}, {3, 4}}]

(* Result of calling f *)
(* {{2, 2}, {1, 3}, {3, 7}} *)

• Amazing to see how the different methods proposed on this page can achieve the same result. I did some Timing. This one gives me 0.000032 second. Others, up to now, vary between 0.000038 and 0.000048. – Jean-Pierre Oct 5 '20 at 20:10
• Using (abusing?) the fact that the first term in each tuple is the position, how about this (0.000034)? SortBy[Last][ ReplaceList[{{1, 2}, {2, 0}, {3, 4}}, {___, {x_, y_}, ___} -> {x, x + y}]] – pudepied Oct 7 '20 at 16:07