Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

This question already has an answer here:

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}
share|improve this question

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

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2  
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
3  
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

5 Answers 5

up vote 5 down vote accepted

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.

share|improve this answer

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.

share|improve this answer
2  
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};
1+list+PadRight[Rest@list,4]

and adapt for arbitrary list

share|improve this answer
3  
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) &

share|improve this answer

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]]
share|improve this answer

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