1
$\begingroup$

If I have some list of data, I often want to remove individual points or chunks of data. I usually do this with Drop[...] but as far as I can tell, it isn't possible to drop multiple "regions". I often end up using nested drops -- which is a bit clumsy

Is there a better way to more intuitively and most importantly, flexibly select regions of a list to drop or exclude?

$\endgroup$
1
  • $\begingroup$ How about Delete? $\endgroup$ Dec 17, 2017 at 20:52

3 Answers 3

2
$\begingroup$

Maybe you can define your own drop function:

MyDrop[list_?ListQ, t : ( _Integer | ( _ ;; _)) ..] := Block[{idx},
   idx = Replace[List[t], x_Integer -> x ;; x, 1];
   idx = Apply[Union, Replace[idx, Span[x_, y_] :> Range[x, y], 1]];
   Delete[list, Map[List, idx]]
   ]; 

Usage example:

MyDrop[Range[10], 5, 7 ;; 9, 6 ;; 8]

{1, 2, 3, 4, 10}

$\endgroup$
1
$\begingroup$

(Note that contrary to the other answers, any valid Drop syntax is supported)

How about something like:

dropList[expr_, pos__] := With[{indices = Range @ Length @ expr},
    expr[[Complement[indices, Take[indices, #]& /@ Unevaluated[Sequence[pos]]]]]
]

For example:

dropList[Range[10], 2, 2;;6;;2, -2]

{3, 5, 7, 8}

Since I use Take to construct the elements to be deleted, any valid Drop (or Take) specification is supported. For example::

dropList[Range[20], 2, {4,6}, 9;;UpTo[100];;2]

{3, 7, 8, 10, 12, 14, 16, 18, 20}

$\endgroup$
0
$\begingroup$

want to remove individual points or chunks of data

Interpreting individual points as an elements of input data, and chunks as positions in input data:

ClearAll[complementF]
complementF[lst_, pos_, el_: {}] := Module[{pf = Composition[Union, Flatten, Query @ pos],
 r = Range @ Length @ lst}, DeleteCases[lst[[Complement[r, pf @ r]]], Alternatives @@ el]]

where pos is the list of positions and the optional last argument el is the list of elements to be removed from lst.

Examples:

complementF[Range[10], {{5}, 7 ;; 9, 6 ;; 8}]

{1, 2, 3, 4, 10}

complementF[Range[10], {{5}, 7 ;; 9, 6 ;; 8}, {2}]

{1, 3, 4, 10}

complementF[Range[10], {;;2, 2 ;; 6 ;; 2, -2;;}]

{3, 5, 7, 8}

complementF[CharacterRange["A", "K"], {{5}, 7 ;; 9, 6 ;; 8}]

{"A", "B", "C", "D", "J", "K"}

complementF[CharacterRange["A", "K"], {{5}, 7 ;; 9, 6 ;; 8}, {"C", "B"}]

{"A", "D", "J", "K"}

$\endgroup$
2
  • $\begingroup$ I think comlementF[{1,1,1,1,1}, {2}] returns an incorrect answer (also, you might want to call it complementF instead of comlementF) $\endgroup$
    – Carl Woll
    Dec 18, 2017 at 1:29
  • $\begingroup$ Thank you @Carl. I will check. $\endgroup$
    – kglr
    Dec 18, 2017 at 1:33

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.