1
$\begingroup$

I have a matrix like below:

mat = {{{a}, {b}, {c}, {d}}, {{a}, {b}, {c}, {d}}}

I want to change it to

{{a, b, c, d}, {a, b, c, d}}

I have tried Flatten function, but was unable to achieve my goal.

$\endgroup$

closed as off-topic by corey979, m_goldberg, MarcoB, eyorble, Henrik Schumacher Feb 25 at 21:02

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – corey979, m_goldberg, MarcoB, eyorble, Henrik Schumacher
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    $\begingroup$ Flatten[#, 1] & /@ mat which is just Map[Flatten[#, 1] &, mat]. See also Pure Functions. $\endgroup$ – corey979 Feb 25 at 14:08
  • 3
    $\begingroup$ Flatten /@ mat $\endgroup$ – J42161217 Feb 25 at 14:09
  • 3
    $\begingroup$ Join @@@ mat.. $\endgroup$ – OkkesDulgerci Feb 25 at 14:16
  • 3
    $\begingroup$ ArrayReshape[mat,{2,4}] $\endgroup$ – N.J.Evans Feb 25 at 14:17
3
$\begingroup$

There are many ways (shown by people in the comments). Personally, I find this one to be the cleanest:

mat[[All, All, 1]]

Take All rows, All columns, and then the 1st element from the list within.

$\endgroup$
2
$\begingroup$

Partition is your friend here, when things get confusing. First Flatten it all the way out.

res=Flatten[mat]

{a, b, c, d, a, b, c, d}

Now Partition into blocks of 4 elements

Partition[res,4]

{{a, b, c, d}, {a, b, c, d}}


Edit

As a performance check, I ran the following tests on the methods in the initial comments, and @Szabolcs's answer. Listed in rank ordering of timing performance. ArrayReshape for the win, but Flatten-Partition in 2nd. EDIT: Surprisingly, it was a little faster to break up the Flatten-Partition into two steps rather than embed them.

mat = RandomInteger[100, {10,000,000, 4, 1}];

AbsoluteTiming[res1 = ArrayReshape[mat, {Length[mat], 4}];]
{0.23, Null}

AbsoluteTiming[res = Flatten@mat; Partition[res, 4];]
{.37, Null}

AbsoluteTiming[Partition[Flatten@mat, 4];]
{0.41, Null}

AbsoluteTiming[res4 = Flatten[mat, {{1}, {2, 3}}];]
{0.523814, Null}

AbsoluteTiming[mat[[All, All, 1]];]
{0.63, Null}

AbsoluteTiming[Flatten /@ mat;]
{1.69, Null}

AbsoluteTiming[Map[Flatten[#, 1] &, mat];]
{1.74, Null}

AbsoluteTiming[Flatten[#, 1] & /@ mat;]
{1.77, Null}

AbsoluteTiming[Join @@@ mat;]
{19.4, Null}
$\endgroup$
  • $\begingroup$ Uhh, why the negative votes? $\endgroup$ – MikeY Feb 25 at 14:13
  • 2
    $\begingroup$ Negative votes probably because your solution is not a recommended way. It goes too far with Flatten and then backtracks with Partition, for which (i) you need the original sublist length 4, and (ii) you assume that all sublists are of equal length. See the above comments for direct solutions without backtracking. $\endgroup$ – Roman Feb 25 at 14:21
  • 1
    $\begingroup$ OK, but I think you've read more into his question than he put in there. While the methods in the comments above all work, many of them require digging into the docs to understand why exactly they work (awesome learning exercise for the novice). Clever but not intuitive. The Flatten-Partition approach is a no-brainer that allows you to implement and move on, and when you are dealing with 2 x 4 matrices... $\endgroup$ – MikeY Feb 25 at 14:35
  • 2
    $\begingroup$ For completeness, please test Flatten[mat, {{1}, {2, 3}}] as well. $\endgroup$ – J. M. will be back soon Feb 25 at 16:00
  • $\begingroup$ Done, you get the Bronze medal. :) $\endgroup$ – MikeY Feb 25 at 16:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.