In Mathematica, what is the cleanest way of taking a list
{r1, r2, r3, ..., rn, a, b}
and returning
{r1, r2, r3, ..., rn, a + b}
or more generally
{r1, r2, r3, ..., rn, f[a, b]}
for some function f
?
In Mathematica, what is the cleanest way of taking a list
{r1, r2, r3, ..., rn, a, b}
and returning
{r1, r2, r3, ..., rn, a + b}
or more generally
{r1, r2, r3, ..., rn, f[a, b]}
for some function f
?
I'd use rules if performance is not a big issue (lists are not packed etc):
lst = {a, b, c, d, e}
In[13]:= Replace[lst, {left__, ntl_, l_} :> {left, f[ntl, l]}, {0}]
Out[13]= {a, b, c, f[d, e]}
lst = {a[1], a[2], a[3], a[4], a[5], a[6], a[7], a, b};
lst /. {a___, b_, c_} -> {a, f[b, c]}
==> {a[1], a[2], a[3], a[4], a[5], a[6], a[7], f[a, b]}
or (ugly):
Append[Take[lst, {1, -3}], f @@ lst[[{-2, -1}]]]
If I hadn't second guessed Simon I would have been first to answer. Nuts. Anyway, here is my late-to-the-party reply.
combineLast =
Module[{x = #},
x[[-2]] = #2 @@ x[[-2 ;;]];
Most[x]
] &;
Comparison:
leoCL[lst_, f_] := Replace[lst, {left__, ntl_, l_} :> {left, f[ntl, l]}, {0}]
a = RandomInteger[1*^9, 5000];
Do[combineLast[a, Plus], {5000}] // Timing
Do[leoCL[a, Plus], {5000}] // Timing
{0.078, Null} {1.844, Null}
Suppose 'list' is defined:
Remove[list];
list = {r1, r2, r2, r4, r5, a, b};
Re-set 'list' to be {r1, r2, r3, r4, r5, a} with the [[-1]] replaced by the sum of the last two elements in 'list'.
list = ReplacePart[Drop[list, -1], -1 -> Plus @@ list[[-2 ;; -1]]]
Thanks for asking this, btw. :)
Here is my take on it:
addLastTwo = Function[Append[Drop[#, -2], Total[Take[#, -2]]]];
In[225]:= addLastTwo[{r1, r2, r3, r4, r5}]
Out[225]= {r1, r2, r3, r4 + r5}
This is slightly faster than Mr.Wizard's solution, although less general:
In[226]:= Do[addLastTwo@a, {10000}] // Timing
Out[226]= {0.25, Null}
In[227]:= Do[combineLast[a, Plus], {10000}] // Timing
Out[227]= {0.39, Null}