6
$\begingroup$

Specifically, I want to take some elements of the lowest level of an array, and then sum over these elements while holding the higher level. Sorry for my vague expression, maybe an example would make it clear: An array of 3 levels:

 try = {{0,{a,b,c}},{{d,e,f,g},{h,i,j}}}

I want to obtain {{0,{a,b}},{{d,e},{h,i}}}, and then sum over to obtain {{0,a+b},{d+e,h+i}}.

Following illustration of Mathematica, i tried:

try[[All,All,1;;2]]

but it could not work. As to summation,

Total[try,{-1}]

could sum over all elements of the last level, however I have no idea how to sum over part of the last level.

Solution?

$\endgroup$

3 Answers 3

7
$\begingroup$

Here's a simple solution that'll act on the deepest level as desired in the question.

Apply[#1 + #2 &, #, {Depth@# -2}]&@ try
(* {{0, a + b}, {d + e, h + i}} *)

Depth gives you the maximum number of indices required to index any level in the expression, plus 1. Since the indexing starts at 0 (the head), the deepest indexable level is Depth[expr]-2.

$\endgroup$
5
  • $\begingroup$ Does your Depth method do something that Apply[# + #2 &, try, {-2}] does not? $\endgroup$
    – Mr.Wizard
    Jun 3, 2012 at 9:50
  • 1
    $\begingroup$ Yes. {-2} only gets the level that is 2 deep. Using Depth as in my answer gets the deepest level, which is what the OP wanted. In this case {-2} happens to also be the correct depth, but for arbitrary expressions, it won't work. Compare the two with try = {{0, {a, b, c, {p, q, r}}}, {{d, e, f, g, {s, t, u}}, {h, i, j}}} $\endgroup$
    – rm -rf
    Jun 3, 2012 at 9:52
  • $\begingroup$ Ah yes I see. I hadn't considered that case. +1 $\endgroup$
    – Mr.Wizard
    Jun 3, 2012 at 9:58
  • $\begingroup$ Impressive! Two more questions. 1) How to generally sum over first n(which could be very large) elements? 2) Could Map similarly be used as the responder rguler do? Actually i am not clear about the differences between Map and Apply. $\endgroup$
    – Mathieu
    Jun 3, 2012 at 14:03
  • $\begingroup$ @Mathieu Yes, you can do Apply[Total@Take[{##}, n] &, #, {Depth[#] - 2}] &@ try to sum over the first n. The Map version will be the same as Mr.Wizard's answer, except that instead of giving an explicit level, use {Depth@try-2} like in mine. $\endgroup$
    – rm -rf
    Jun 3, 2012 at 16:06
7
$\begingroup$
 Map[Total@Take[#, 2] &, try, {-2}]
 (* ==> {{0, a + b}, {d + e, h + i}} *)

Note: from docs on Map (section More Information):

A negative level -n consists of all parts of expr with depth n.

$\endgroup$
6
$\begingroup$

Perhaps this?

f[x_List] := Take[x, 2]
f[x_] := x

Total[Map[f, try, {2}], {-1}]
{{0, a + b}, {d + e, h + i}}

Alternatively:

Replace[try, {a_, b_, ___} :> {a, b}, {2}] ~Total~ {-1}

Or perhaps more generally:

Replace[try, x_List :> x[[;; 2]], {2}] ~Total~ {-1}

More directly:

Apply[# + #2 &, try, {-2}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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