# How to extract a contiguous s_1 x s_2 x … x s_d subarray from an n_1 x n_2 x … x n_d array, where the dimension d is a variable

Given a multidimensional array, such as the 3-dimensional 2 x 2 x 3 array

{
{{a,b,c},{d,e,f}},
{{g,h,i},{j,k,l}}
}


How can I extract an arbitrary 3-dimensional contiguous subarray, such as slice 1, rows 1-2 and columns 2-3, which is

{
{{b,c},{e,f}}
}


This is not too hard, using Part, Take, Extract, etc.

But how can I do it for an array of arbitrary dimension d? Must I use recursion somehow ?

• "This is not too hard, using Part, Take, Extract, etc." What have you tried? Can you share some code? – dr.blochwave Mar 19 '15 at 12:55

It is very easy using Part, which allows specifications of arbitrary depth, and Span:

m = {{{a, b, c}, {d, e, f}}, {{g, h, i}, {j, k, l}}}

m[[1, 1 ;; 2, 2 ;; 3]]

{{b, c}, {e, f}}


If you want full bracket depth in the output make any single part specification a List:

m[[{1}, 1 ;; 2, 2 ;; 3]]

{{{b, c}, {e, f}}}


This is an attempt to address an example provided in the comments. As I understand it your example can be reduced to:

x = Fold[Partition, Range@12, {3, 2}]

MapThread[# ;; # + #2 - 1 &, {{1, 2, 2}, {2, 1, 2}}]

x[[##]] & @@ %

{{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}}}

{1 ;; 2, 2 ;; 2, 2 ;; 3}

{{{5, 6}}, {{11, 12}}}


There is nothing about this that is restricted to three dimensions as far as I can see.
Here is the same code again with a larger tensor:

x = Fold[Partition, Range@72, {3, 4, 2}];

x[[##]] & @@ MapThread[# ;; # + #2 - 1 &, {{1, 2, 1, 2}, {2, 1, 2, 2}}]

{{{{14, 15}, {17, 18}}}, {{{38, 39}, {41, 42}}}}


Other ways to write the same operation:

a = {1, 2, 1, 2};
b = {2, 1, 2, 2};

Inner[# ;; # + #2 - 1 &, a, b, x[[##]] &]

{{{{14, 15}, {17, 18}}}, {{{38, 39}, {41, 42}}}}

Take[x, ##] & @@ ({a, a + b - 1}\[Transpose])

{{{{14, 15}, {17, 18}}}, {{{38, 39}, {41, 42}}}}

Take[Drop[x, ##] & @@ (a - 1), ##] & @@ b

{{{{14, 15}, {17, 18}}}, {{{38, 39}, {41, 42}}}}

• Thank you very much @Mr.Wizard and blochwave. Here is an example of what I mean: arraydims = {2, 2, 3}; cases = Tuples[{0, 1}, arraydims]; badsubarraydims = {2, 1, 2};badsubarrayoffset={1, 2, 2};cases[[792]] – Simon Mar 19 '15 at 19:39