1
$\begingroup$

Suppose I have a list

{a[1], a[2], a[3], ...} 

and a function

y = f[x1, x2]

Is it possible to return a list like

{a[1], f[a[2],a[1]], f[a[3], f[a[2],a[1]]], ... ]

This may look like a little bit confusing. Actually, it just applies the function across consecutive elements in this list in order.

1st time, take a[1] and a[2] and act on a[2]:

{a[1], f[a[2], a[1]], a[3], ...} 

2nd time, take a[3] and the new a[2] and act on a[3]:

{a[1], f[a[2], a[1]], f[a[3], f[a[2], a[1]]], ...} 

In other words, although the problem is very similar to Span a function across several consecutive elements in a list, the order / history of the application matters.

Is there a way that it can be realized elegantly without using For loop?

$\endgroup$

2 Answers 2

6
$\begingroup$

Use FoldList:

FoldList[f[#2, #1]&, Array[a, 5]]

{a[1], f[a[2], a[1]], f[a[3], f[a[2], a[1]]], f[a[4], f[a[3], f[a[2], a[1]]]], f[a[5], f[a[4], f[a[3], f[a[2], a[1]]]]]}

$\endgroup$
1
  • $\begingroup$ Thanks so much for the quick answer. I couldn't believe there exists exactly a function designed for this. $\endgroup$
    – Tom
    Jul 10, 2017 at 16:17
0
$\begingroup$
Map[
Reverse@Array[a, #] //. {a[x_], p : Repeated[a[_], {2, Infinity}]} :> 
{a[x], {p}} /. List :> f &, Range[5]]

(* {a[1], f[a[2], a[1]], f[a[3], f[a[2], a[1]]], f[a[4], f[a[3], f[a[2], a[1]]]],
f[a[5], f[a[4], f[a[3], f[a[2], a[1]]]]]} *)
$\endgroup$

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