How can I remove the singleton dimensions of an array? [duplicate]

If I have an array A, for which Dimensions[A] is {9, 9, 1, 1, 3, 4}, how can I convert A' into an array with dimensions {9, 9, 3, 4}?

I think there is a built-in function for this, but I can't remember its name.

-

marked as duplicate by Michael E2, m_goldberg, Yves Klett, Kuba, ArtesNov 29 '13 at 15:08

What is meant by conversion of dimension ? Repositioning element or just removing 1 from list ? –  Rorschach Nov 23 '13 at 9:13
It is just the same array logically; however, mathematica's Dimensions[] function will identify them as different arrays with different dimensions. –  LCFactorization Nov 23 '13 at 9:17
E.g, If I have {{a,b},{c,d}}, it is {2,2} in sizes; sometimes it can also be {2,2,1,1,1}; How to make sure mathematica's Dimensions only obtain the simplest result {2,2}? –  LCFactorization Nov 23 '13 at 9:18
Flatten does work, but it is complicate this way; there should be a simpler way with only one simple Function but I forget the name. –  LCFactorization Nov 23 '13 at 9:27

You could get the array's dimensions, remove the 1's and use that in ArrayReshape:

array = Array[f, {9, 9, 1, 1, 3, 4}];
new = ArrayReshape[array, Dimensions[array] ~DeleteCases~ 1];
Dimensions[new]
(*  {9, 9, 3, 4} *)


If efficiency is not important you could use a replacement rule:

new = array //. {x_} :> x
Dimensions[new]
(*  {9, 9, 3, 4} *)

-
Thanks. It seems I was confused by Matlab's "squeeze" which removes singleton dimensions while Mathematica doesnot have such a function. –  LCFactorization Nov 24 '13 at 0:01
ArrayReshape is a thing now? Sweet! –  Pillsy Nov 24 '13 at 4:02

Another way to use Flatten is to collect the trivial (single-element) levels with the first nontrivial level:

flattenTrivialLevels[array_] :=
Flatten[array,
Flatten[{Position[#, _?(# > 1 &), 1, 1], Position[#, 1]} &@ Dimensions[array]]]


OP's test case (compared with Simon Woods' elementary replacement method):

array = RandomInteger[10, {9, 9, 1, 1, 3, 4}];
flat = flattenTrivialLevels[array];
new = array //. {x_} :> x;
Dimensions[flat]
flat === new

(* {9, 9, 3, 4} *)
(* True *)


The Flatten command being used is Flatten[array, {1, 3, 4}].

An arbitrary variation:

array = RandomInteger[10, {1, 9, 1, 9, 1, 1, 3, 1, 1, 1, 4}];
flat = flattenTrivialLevels[array];
new = array //. {x_} :> x;
Dimensions[flat]
flat === new

(* {9, 9, 3, 4} *)
(* True *)

-
array = Array[f, {9, 9, 1, 1, 3, 4}];
Dimensions[array]


{9,9,1,1,3,4}

newArray=Flatten[array , {{1}, {2}, {5}, {6, 3, 4}}];
Dimensions[newArray]


{9,9,3,4}

-
Thank you. The desired solution should be that, the user don't have to use the original array's dimension information. If these are available, I would prefer to use ArrayReshape[] –  LCFactorization Nov 23 '13 at 9:36