# Combining duplicate elements in a list

I have a list of the form,

mylist = {{0.1, 1.2},{0.3, 2.1},{0.1, 0.5},{0.4, 0.4},{0.4, 0.1},{0.1, 1.6}}


I would like to create a function, myfn, that takes a list and outputs a new list where the sublists with the same first element are combined, by adding the second elements together. For example in the above, I expect the output:

myfn[mylist]
(* Out: {{0.1, 3.3}, {0.3, 2.1}, {0.4, 0.5}} *)


I have the following piece of code that does the job, but it looks not particularly elegant and I was wondering if there are better ways to achieve this result?:

myfn[list_] := Module[{listnew = {list[[1]]}, pos},
Do[
Which[
Length@Position[First@Transpose[listnew], list[[i, 1]]] == 0,
listnew = Join[listnew, {list[[i]]}],

Length@Position[First@Transpose[listnew], list[[i, 1]]] == 1,
pos = Flatten@Position[listnew, list[[i, 1]]];
listnew[[pos[[1]], 2]] +=  list[[i, 2]],

True,
Print["Never get here in myfn. Aborting now..."]; Abort[]
]
, {i, 2, Length[list]}];
listnew
]


Use GatherBy to collect members the list by their first elements, then total the second elements.

mylist = {{0.1, 1.2},{0.3, 2.1},{0.1, 0.5},{0.4, 0.4},{0.4, 0.1},{0.1, 1.6}};

{#[[1, 1]], Total[#[[All, 2]]]} &/@ GatherBy[mylist, First]
(* {{0.1, 3.3}, {0.3, 2.1}, {0.4, 0.5}} *)

Clear["Global*"]
mylist = {{0.1, 1.2}, {0.3, 2.1}, {0.1, 0.5}, {0.4, 0.4}, {0.4,
0.1}, {0.1, 1.6}}

GroupBy[mylist, First -> Last, Total] // KeyValueMap[List]


{{0.1, 3.3}, {0.3, 2.1}, {0.4, 0.5}}

An easy way to get an equivalent representation to what you desire is:

Total /@ GroupBy[mylist, First -> Last]
(* <|0.1 -> 3.3, 0.3 -> 2.1, 0.4 -> 0.5|> *)


You can transform this to your exact expected result:

KeyValueMap[List, Total /@ GroupBy[mylist, First -> Last]]
(* {{0.1, 3.3}, {0.3, 2.1}, {0.4, 0.5}} *)


One way to do it:

List @@@ (Merge[Rule @@@ mylist, Total] // Normal)


A variant of bmf's answer using MapApply (new in 13.1)

KeyValueMap[List] @ Merge[Total] @ MapApply[Rule] @ list


{{0.1, 3.3}, {0.3, 2.1}, {0.4, 0.5}}

A hash-free variant of creidhne's answer using Query

Query[All, {1 -> First, 2 -> Total}] @ Map[Transpose] @ GatherBy[list, First]
`

{{0.1, 3.3}, {0.3, 2.1}, {0.4, 0.5}}