4
$\begingroup$

I have a list of ordered pairs:

{{1, 1}, {1, 2}, {2, 4}, {1, 2}, {1, 2}, {2, 4}, {2, 4}, {2, 4}, {4, 4}}

If two pairs {x_1, y_1} and {x_2, y_2} are such that y_1 = y_2, then I want to "combine" them by adding x_1 + x_2 to create the pair {x_1 + x_2, y_1}.

For the 9 ordered pairs above, the desired final result would be:

{{1, 1}, {3, 2}, {12, 4}}

I have tried using Sort and Tally but without success.

$\endgroup$

4 Answers 4

6
$\begingroup$

As often, this can be achieved in many different ways. For example, you can first use GatherBy to group elements together by their last element, then use Map and calculate the Total:

list = {{1, 1}, {1, 2}, {2, 4}, {1, 2}, {1, 2}, {2, 4}, {2, 4}, {2, 4}, {4, 4}};

{Total[#[[All, 1]]], #[[1, 2]]} & /@ GatherBy[list, Last]
(* {{1, 1}, {3, 2}, {12, 4}} *)
$\endgroup$
7
$\begingroup$

Maybe something along these lines:

input = {{1, 1}, {1, 2}, {2, 4}, {1, 2}, {1, 2}, {2, 4}, {2, 4}, {2, 4}, {4, 4}};
KeyValueMap[Reverse@*List, GroupBy[input, Last -> First, Total]]
(* {{1, 1}, {3, 2}, {12, 4}} *)
$\endgroup$
6
$\begingroup$

Let's try some 1980's style pattern matching list hacking, the kinds of stuff we used to write decades before they introduced all these new fangled associations and regions and version 2,3,...14 ways of programming.

list={{1,1},{1,2},{2,4},{1,2},{1,2},{2,4},{2,4},{2,4},{4,4}};
list//.{a___,{head1_,tail_},b___,{head2_,tail_},c___}->{a,{head1+head2,tail},b,c}

which almost instantly returns

{{1,1},{3,2},{12,4}}
$\endgroup$
3
$\begingroup$
pairs = {{1, 1}, {1, 2}, {2, 4}, {1, 2}, {1, 2}, {2, 4}, {2, 4}, {2, 4}, {4, 4}};

Another alternative is to use the flexibility of Reap and Sow:

Reap[Sow[#[[1]], #[[2]]] & /@ pairs, _, {Total@#2, #1} &][[2]]

{{1, 1}, {3, 2}, {12, 4}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.