# How can I extract multiple spans from a list?

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 ( ).

-

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;;...

-
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.

-

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}
}

-