Refer to next element of list when iterating using Map [duplicate]

Is it possible to refer to the next element of the list when I'm using Map or should I always use For in this case?
For example I can write:

(1 + #1) & /@ {a, b, c, d}


but I can not write:

(1 + #1 + #2) & /@ {a, b, c, d}


The problem with the last element should be also avoided. So in last example I would like to get something like

{ 1 + a + b, 1 + b + c, 1 + c + d, 1 + d}

-

marked as duplicate by Mr.Wizard♦Oct 22 '13 at 11:48

It is possible if you use MapIndexed. Also, #2 refers to the second argument of a function, not the second element of a list (or the next). –  rm -rf Oct 22 '13 at 7:42
I tend to use Partition in these situations, like (1 + #1 + #2) & @@@ Partition[{a, b, c, d}, 2, 1] or MapThread[(1 + #1 + #2) &, Transpose@Partition[{a, b, c, d}, 2, 1]]. I hope somebody will show a smarter way here... –  Pinguin Dirk Oct 22 '13 at 7:49

One can use MapIndexed to access the next (or previous or any arbitrary offset) element of the currently mapped element. However, you also need to make checks so that you don't index it beyond its bounds. For example:

With[{list = Range@5}, MapIndexed[{f@#, f@list[[Mod[#2[[1]] + 1, Length@list, 1]]]} &, list]]
(* {{f[1], f[2]}, {f[2], f[3]}, {f[3], f[4]}, {f[4], f[5]}, {f[5], f[1]}} *)


Here, I've chosen to wrap the index back to the first element, but you can choose something else.

As Pinguin Dirk mentioned, Partition is also an option if your offsets are regular:

With[{list = Range@5}, {f@#, f@#2} & @@@ Partition[list, 2, 1, {1, 1}]]


Use the higher arguments of Partition to control how the endpoints/padding should be done.

-

One way to do this is as follows:

Map[Total[#] &, Partition[{a, b, c, d}, 2, 1]] + 1


the result is

(* {1 + a + b, 1 + b + c, 1 + c + d}   *)


Alternatively it can be written down in the pure function notations:

(1 + (#[[1]] + #[[2]]) &) /@ Partition[{a, b, c, d}, 2, 1]


The result is the same.

-
Or 1 + #1 + #2 & @@@ Partition[{a, b, c, d}, 2, 1] –  Chris Degnen Oct 22 '13 at 8:07
@ChrisDegnen: pretty much my comment above :) –  Pinguin Dirk Oct 22 '13 at 8:12
@Pinguin Dirk Yes, it is the same as in your comment. I apologize to have skipped reading the comments and turned to answer at the spot. –  Alexei Boulbitch Oct 22 '13 at 11:35
@AlexeiBoulbitch: no problem at all! I am glad I wasn't the only one with that idea (see the last sentence in my comment) :) all good! –  Pinguin Dirk Oct 22 '13 at 11:38

To achieve the result: {1+a+b,1+b+c,1+c+d,1+d} [noting (1 + (#[[1]] + #[[2]]) &) /@ Partition[{a, b, c, d}, 2, 1] -> {1 + a + b, 1 + b + c, 1 + c + d}] you could simply do:

list={a,b,c,d};


-
Alternatively 1 + list + PadLeft[list, 4, 0, 1] –  Simon Woods Oct 22 '13 at 8:56

Use Partition to produce {{a, b}, {b, c}, {c, d}, {d}} then for the operation in your example total the sublists at the second level and + 1:

1 + Total[Partition[{a, b, c, d}, 2, 1, {1, 1}, {}], {2}]


Note the partitioning here differs from the other comments and answers which aren't delivering the answer you requested {1+a+b,1+b+c,1+c+d,1+d} as far as I can tell.

More generally you would do:

f @@@ Partition[{a, b, c, d}, 2, 1, {1, 1}, {}]


In your example f would be (1 + #1 + ##2) &

-

Another possibility is to use NestList and carry the current index so you can manipulate it or control it.

list = {a, b, c, d} ;
f[x_, y_] = 1 + x + y ;

NestList[
{#[[1]]+1, f[list[[#[[1]]+1]], If[#[[1]]+1+1 <= Length[list], list[[#[[1]]+1+1]], 0]]} &,
{1, f[list[[1]], list[[2]]]}, Length[list]-1][[All,2]]

-