# 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!!

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}}} *)


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]]

(* {{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. Oct 5, 2020 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}]] Oct 7, 2020 at 16:07