3

I know in Mathematica, I can do

A = Range[100];
B = A[[50 ;; 60]]

B will then contain the 50th through 60th elements of A.

Now, what if I wanted B to take 10th through 40th plus 60th through 80th. Can I do so in one expression such as

B = A[[10 ;; 40 + 60 ;; 80]]

Apparently the above code doesn't work. But I don't want to generate a separate list to do so. Is there a short-cut or elegant way of combining two or more spans in one Part expression?

I hope ;; is treated as range. Also, typeing Part, i.e., [[]], really takes a lot of time to type. I wish Mathematica 10 will shorten it to < > or ( ).

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
bboczeng
  • 449
  • 5
  • 9

3 Answers3

5
list = CharacterRange["A", "Z"];
spans = {3 ;; 6, 10 ;; 16};

list[[Join @@ Range @@@ spans]]
(* {"C","D","E","F","J","K","L","M","N","O","P"} *)

spans2 = {3 ;; 6, 10 ;; 16 ;; 2};
list[[Join @@ Range @@@ spans2]]
(* {"C","D","E","F","J","L","N","P"} *)

Or, of course, Part[list,Join @@ Range @@@ spans].

NOTE: this works only for some forms of Span with explicit indices; it fails for cases like ;;-1;; or ;;;; or ;;All;;...

kglr
  • 394,356
  • 18
  • 477
  • 896
4
list = Range[100];
subranges = {10 ;; 20, 30 ;; 40};

subRanges = Module[{l = ConstantArray[0, Length@#]},
    (l[[#]] = 1) & /@ #2;
    Pick[#, l, 1]] &;

subRanges[list, subranges]

(* {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40} *)

You could just use

Join @@ (list[[#]] & /@ subranges)

for the same result.

See also Undocumented form for Extract, it might be useful here.

ciao
  • 25,774
  • 2
  • 58
  • 139
4

Here is an example using the undocumented form of Extract (just to have that answer here) uncovered by rasher and linked in his answer.

lis = Range[100];

Rest @ Extract[lis, {{0}, {10 ;; 40}, {60 ;; 80}}]

Which gives:

{
 {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 
  27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}, 
 {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 
  79, 80}
}
RunnyKine
  • 33,088
  • 3
  • 109
  • 176