TransWikia.com

DeleteCases depending on all elements

Mathematica Asked by fravity on March 19, 2021

I have a listed of Tupels

list = {{10, 5}, {20, 4}, {20, 3}, {10, 6}};

If there are two elements a and b for which

a[[1]] <= b[[1]] && a[[2]] <= b[[2]]

then I would like to delete the element a.
If I implement this via for loops,

For[i = Length@list, i > 0, i--,
  For[j = Length@list, j > 0, j--,
        If[i != j && list[[i, 1]] <= list[[j, 1]] && list[[i, 2]] <= list[[j, 2]], list = Delete[list, i]; Break[];];
    ];
  ];

then this works but seems to be quite slow. As I need to implement this for many elements, I thought there could be a better/more performant way to solve this directly with Mathematica functions, like DeleteCases. Do you have an idea?

Thanks a lot!

2 Answers

list = {{10, 5}, {20, 4}, {20, 3}, {10, 6}};

1. You can use the function Internal`ListMin as follows:

- Internal`ListMin[-list]
 {{20, 4}, {10, 6}}

2. You can also use DeleteDuplicates:

DeleteDuplicates[ReverseSort@list, And @@ Thread[GreaterEqual[##]] &]
{{20, 4}, {10, 6}}

3. ... and SequenceReplace:

 SequenceReplace[Sort @ list, 
  {a__} /; (And @@ Thread[LessEqual[a]]) :> Last[{a}]]
{{10, 6}, {20, 4}}

Correct answer by kglr on March 19, 2021

You can sort the list into ascending order using plain old Sort, and then Split it into sublists where the second element is ascending. The Last element of each such sublist will be the one you want to keep:

Last /@ Split[Sort[list], #1[[2]] <= #2[[2]] &]
(* {{10, 6}, {20, 4}} *)

If you need the operation to keep the remaining elements in their original order, you can sort again based on PositionIndex.

SortBy[
 Last /@ Split[Sort[list], #1[[2]] <= #2[[2]] &],
 PositionIndex[list]]
(* {{20, 4}, {10, 6}} *)

Answered by Pillsy on March 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP