7
$\begingroup$

Suppose I have some list with duplicates by some condition and I want to take the duplicates and apply some function to choose which duplicate to keep. Is there an efficient way to apply this transformation?

To clarify here is an example. Consider a list with elements with duplicate first elements:

list={{2, 0.2}, {3, 0.}, {2, 0.1}, {4, 0.9}, {6, 0.3}, {3,  0.4}, {6, 0.3}}

Now I can apply, DeleteDuplicatesBy[list, #[[1]] &] and it will drop all the second instances of the duplicates in the list. But instead I want to do something else, say keep the duplicate with the maximum second value. This would look something like (my hypothetical function takes the arguments: list, function to find duplicates, function to act on duplicate list):

CombineDuplicateBy[list,#[[1]]&,MaximalBy[#,#[[2]]&]]
{{2, 0.2}, {4, 0.9},{3,  0.4}, {6, 0.3}}

Notice my hypothetical output deleted elements {3, 0.} and {6, 0.3} since they were duplicates and had a smaller (or equal) second value.

$\endgroup$
2
  • 6
    $\begingroup$ Look into GatherBy. In particular, MaximalBy[#, #[[2]] &, UpTo[1]] & /@ GatherBy[list, #[[1]] &]. $\endgroup$
    – user484
    Jan 21, 2018 at 22:10
  • 3
    $\begingroup$ You could also use SortBy, as in DeleteDuplicatesBy[Reverse@SortBy[list, Last], First]. $\endgroup$ Jan 21, 2018 at 22:15

2 Answers 2

8
$\begingroup$

You could use GroupBy:

GroupBy[list, First, First@*MaximalBy[Last]]
Values @ %

<|2 -> {2, 0.2}, 3 -> {3, 0.4}, 4 -> {4, 0.9}, 6 -> {6, 0.3}|>

{{2, 0.2}, {3, 0.4}, {4, 0.9}, {6, 0.3}}

$\endgroup$
4
$\begingroup$

Also

KeyValueMap[{#, Max @ #2}&] @ Merge[Rule @@@ list, Identity]
Join @@ TakeLargestBy[Last, 1] /@ GatherBy[list, First]
Join @@ MaximalBy[#, Last, 1]& /@ GatherBy[list, First]

{{2, 0.2},{3, 0.4},{4, 0.9},{6, 0.3}}

$\endgroup$

Your Answer

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

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