10
$\begingroup$

I have two lists which I would like to combine. One is of a random structure, which might be:

l1={{3, 2, 4, 2}, {2, 3}, {4, 3}, {{2, 2}}, {{3, 3}}, {3, 2}}

where the elements in each sublist may themselves be numbers, or lists.

From this, I create a list given by:

l2=Join[{0}, Accumulate[Flatten[l1, 1]]]

which gives in this case:

{0, 3, 5, 9, 11, 13, 16, 20, 23, {25, 25}, {28, 28}, {31, 31}, {33, 33}}

I now want to go through the original list, and append to each entry in that list, an entry from the second, in order, to end up with:

{{{3, 0}, {2, 3}, {4, 5}, {2, 9}}, {{2, 11}, {3, 13}}, {{4, 16}, {3, 20}}, {{{2, 2}, 23}}, {{{3, 3}, {25, 25}}}, {{3, {28, 28}}, {2, {31, 31}}}}

I can do this using a loop, but I would like to find a functional way to write it. I have tried using various map, list and thread commands, but so far have been unable to solve it.

$\endgroup$
1
  • $\begingroup$ Related: (3585) $\endgroup$
    – Mr.Wizard
    Jan 12 '17 at 13:30
7
$\begingroup$

This matches your output:

Module[{i = 1},
  Map[{#, l2[[i++]]} &, l1, {2}]
]

If you don't need l2 separately you can eliminate the use of Accumulate entirely with:

Module[{t = 0},
  Map[{#, # &[t, t += #]} &, l1, {2}]
]

The inner function # &[t, t += #] is just a way to AddTo t but return the old value of t. Equivalently: First[{t, t += #}].

$\endgroup$
4
  • $\begingroup$ Beautiful, thank you! $\endgroup$ Jan 12 '17 at 13:22
  • $\begingroup$ @Jonathan You're welcome, and I am glad I could help. As always however I recommend waiting 24 hours before Accepting an answer to encourage everyone who has an answer to post it. $\endgroup$
    – Mr.Wizard
    Jan 12 '17 at 13:24
  • $\begingroup$ @Jonathan Please see my update. $\endgroup$
    – Mr.Wizard
    Jan 12 '17 at 13:53
  • $\begingroup$ thanks for the tip. regarding accepting the answer. I shall keep this in mind in the future. Indeed I don't need the intermediate step, so the update is very useful too. $\endgroup$ Jan 12 '17 at 15:44
4
$\begingroup$

Also,

l3 = Internal`PartitionRagged[Most@l2, Length /@ l1];
Transpose /@ Transpose[{l1, l3}]

{{{3, 0}, {2, 3}, {4, 5}, {2, 9}},
{{2, 11}, {3, 13}},
{{4, 16}, {3, 20}},
{{{2, 2}, 23}},
{{{3, 3}, {25, 25}}},
{{3, {28, 28}}, {2, {31, 31}}}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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