6
$\begingroup$

I have a list as follows:

lis1={{{a1,b1,c1,d1,e1},{a2,b2,c2,d2,e2}},
{{a3,b3,c3,d3,e3},{a4,b4,c4,d4,e4}}}

and would like to delete certain elements from it resp. pick certain elements to get a list as follows

lis2= {{{a1,c1,e1},{a2,c2,e2}},
    {{a3,c3,e3},{a4,c4,e4}}}

My problem is that the data I would like to select are not in an consecutive order (otherwise I could use the Part function). Does anyone have an hint?

$\endgroup$

5 Answers 5

7
$\begingroup$

You actually can still use the Part function!

If you know the positions explicitly you can try:

lis1[[All, All, {1, 3, 5}]]

Or, if they follow a regular pattern:

lis1[[All, All, 1 ;; 5 ;; 2]]
$\endgroup$
9
$\begingroup$

Just learned from this answer by ciao that Downsample is made for this kind of task:

Downsample[#, {1, 2}] & /@ lis1
(* {{{a1, c1, e1}, {a2, c2, e2}}, {{a3, c3, e3}, {a4, c4, e4}}} *)

You can also use Take, Drop and Extract to get the same result:

Take[#, All, {1, -1, 2}] & /@ lis1
Drop[#, {}, {2, -1, 2}] & /@ lis1
First@Rest@Extract[lis1, {{0}, {;; , ;; , ;; ;; 2}}]

You can use arbitrary lists for Part specifications with Part and Extract. For example

#[[All, ;; , {1, 4, 5}]] &@lis1  (* or *)
First@Rest@Extract[lis1, {{0}, {All, ;; , {1, 4, 5}}}]

both give all rows and columns 1, 4 and 5 in all matrices in lis1:

(* {{{a1, d1, e1}, {a2, d2, e2}}, {{a3, d3, e3}, {a4, d4, e4}}} *)
$\endgroup$
5
  • $\begingroup$ That only works for the specific example. OP said: "My problem is that the data I would like to select are not in an consecutive order (otherwise I could use the Part function)." $\endgroup$
    – rm -rf
    May 2, 2015 at 17:57
  • $\begingroup$ @TheToad, i may be wrong, but i thought the quote meant the OP was not aware of the part specifications other than from;;to (since Part specs can be any list). $\endgroup$
    – kglr
    May 2, 2015 at 18:08
  • $\begingroup$ @TheToad Even though the origins of the name change are clear, it will take (me) some time to get used to. Is it planned as permanent? $\endgroup$ May 2, 2015 at 19:34
  • 1
    $\begingroup$ @LeonidShifrin It was just for fun, mostly. I came across an image that I really liked and just went along with it :) How long I'll keep it, I don't know, lol. I've always treated online personas as ephemeral and have fun changing things around but I can see how it might be confusing for others, especially when there are some artifacts and other bread crumbs lying around :) I can revert if you'd like me to/find it confusing. $\endgroup$
    – rm -rf
    May 4, 2015 at 4:34
  • $\begingroup$ @TheToad Oh no, by all means keep it as long as you want :). It's fun to everyone. I wasn't really serious. $\endgroup$ May 4, 2015 at 9:00
5
$\begingroup$
lis1 /. b1|d1|b2|d2|b3|d3|b4|d4->Sequence[]
$\endgroup$
1
$\begingroup$
lis1 = {{{a1, b1, c1, d1, e1}, {a2, b2, c2, d2, e2}}, {{a3, b3, c3, 
    d3, e3}, {a4, b4, c4, d4, e4}}};

MapAt[Nothing, {All, All, {2, 4}}] @ lis1

ReplaceAt[_ :> Nothing, {All, All, {2, 4}}] @ lis1

Both give the expected result:

{{{a1, c1, e1}, {a2, c2, e2}}, {{a3, c3, e3}, {a4, c4, e4}}}

ReplaceAt was introduced in V 13.1 and has the advantage that we can use the usual Condition syntax. Example:

ReplaceAt[lis1, x_ /; SymbolName[x] != "b1" :> Nothing, {All, All, {2, 4}}]

{{{a1, b1, c1, e1}, {a2, c2, e2}}, {{a3, c3, e3}, {a4, c4, e4}}}

$\endgroup$
1
$\begingroup$

Another way using ReplaceAll and Span:

(lis1 /. x_?VectorQ :> x[[1 ;; 5 ;; 2]]) === lis2

(*True*)

Or using ReplaceAll and Select:

(lis1 /. x_?VectorQ :> Select[x, OddQ[Det@Position[x, #]] &]) === lis2

 (*True*)

Thanks to @eldo for showing me the following shorter way:

  (lis1 /. x_?VectorQ :> x[[;; ;; 2]]) === lis2

  (*True*)
$\endgroup$
2
  • 1
    $\begingroup$ Or, even shorter, lis1 /. x_?VectorQ :> x[[;; ;; 2]] +1 $\endgroup$
    – eldo
    Sep 15 at 6:20
  • $\begingroup$ Thanks, mate! :-) $\endgroup$ Sep 15 at 6:27

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.