Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Data Days is here! Join us now for 60+ days of learning, challenges, and connection. Learn more

Reply
Dicken
Post Prodigy
Post Prodigy

Rolling accumulation

Hi,
I have been trying various methods of a rolling accumultion or bucketiing;  so  buckets of 3  =  {1..10} = 
{  {1}, {1,2}, { 1,2,3}, { 2,3,4} , {3,4,5}, {4,5,6}, {5,,6.7}, { 6,7,8} , { 7,8,9}, { 8,9,10} 

so there is always adding index and firstN / lastN as a table,
but i have these two methods with generate or transform;

let
  alist = {1 .. 15},
  window = 3,
  bucket = List.Generate(
    () => 1,
    each _ <= List.Count(alist),
    each _ + 1,
    each if _ < 4 then List.Range(alist, 0, _) else List.Range(alist, _ - window, window)
  )
in
  bucket



let
  alist = {1 .. 15},
  window = 3,
  pos = {1 .. List.Count(alist)},
  bucket = List.Transform(
    pos,
    (x) => if x < 4 then List.Range(alist, 0, x) else List.Range(alist, x - window, window)
  )
in
  bucket

a slightly efficient method seems to be to pad the list with zeros, so here 2 window - 1 ,
which removes the logical test but does meant the first is {0,0,1}

has anyone any other approaches using different functions? perhaps using custom comparer in
groupby ?

Richard 




2 ACCEPTED SOLUTIONS
pcoley
Impactful Individual
Impactful Individual

@Dicken please try with: 

let
    alist = {1 .. 15},
    window = 3,
    pad = List.Repeat({0}, window - 1),           // {0, 0}
    padded = List.Combine({pad, alist}),          // {0,0,1,2,...,15}
    positions = {0 .. List.Count(alist) - 1},     // 0-based indices for final result
    buckets = List.Transform(
        positions,
        each List.Range(padded, _, window)        // always take exactly 'window' items
    )
in
    buckets
If I helped solve your problem, mark this post as a solution.
Kudos are Welcome! | AI assisted for clarity of wording. |

View solution in original post

pcoley
Impactful Individual
Impactful Individual

@Dicken Another option could be with List.Accumulate: 

let
    alist = {1 .. 15},
    window = 3,
    buckets = List.Accumulate(
        {1 .. List.Count(alist)},
        {},
        (state, current) => 
            state & {
                if current <= window 
                then List.Range(alist, 0, current)
                else List.Range(alist, current - window, window)
            }
    )
in
    buckets
If I helped solve your problem, mark this post as a solution.
Kudos are Welcome! | AI assisted for clarity of wording. |

View solution in original post

7 REPLIES 7
slorin
Super User
Super User

Hi
Another solution

= List.Transform(
{1..List.Count(alist)},
(i)=> List.Transform(
List.Numbers(List.Max({0, i-window}), window),
each alist{_}))


Stéphane

AlienSx
Super User
Super User

let
    lst = {1..15},
    window = 3, 
    fx = (i, s) => if i = window 
        then List.Zip(s) 
        else @ fx(i + 1, {List.Repeat({null}, i) & List.RemoveLastN(lst, i)} & s)
in
    fx(0, {})
pcoley
Impactful Individual
Impactful Individual

@Dicken Another option could be with List.Accumulate: 

let
    alist = {1 .. 15},
    window = 3,
    buckets = List.Accumulate(
        {1 .. List.Count(alist)},
        {},
        (state, current) => 
            state & {
                if current <= window 
                then List.Range(alist, 0, current)
                else List.Range(alist, current - window, window)
            }
    )
in
    buckets
If I helped solve your problem, mark this post as a solution.
Kudos are Welcome! | AI assisted for clarity of wording. |

especially like the accumulate version. 

pcoley
Impactful Individual
Impactful Individual

@Dicken also you can try with List.Generate:

let
    alist = {1 .. 15},
    windowSize = 3,
    result = List.Generate(
        () => [idx = 0, win = {}],
        each [idx] < List.Count(alist),
        each [
            idx = [idx] + 1,
            win = if [idx] < windowSize 
                  then List.Range(alist, 0, [idx] + 1)
                  else List.Range(alist, [idx] - windowSize + 1, windowSize)
        ],
        each [win]
    )
in
    result
If I helped solve your problem, mark this post as a solution.
Kudos are Welcome! | AI assisted for clarity of wording. |

Thaanks all, that's enough to be going on with i shall go through them all. 

pcoley
Impactful Individual
Impactful Individual

@Dicken please try with: 

let
    alist = {1 .. 15},
    window = 3,
    pad = List.Repeat({0}, window - 1),           // {0, 0}
    padded = List.Combine({pad, alist}),          // {0,0,1,2,...,15}
    positions = {0 .. List.Count(alist) - 1},     // 0-based indices for final result
    buckets = List.Transform(
        positions,
        each List.Range(padded, _, window)        // always take exactly 'window' items
    )
in
    buckets
If I helped solve your problem, mark this post as a solution.
Kudos are Welcome! | AI assisted for clarity of wording. |

Helpful resources

Announcements
Fabric Data Days is here Carousel

Fabric Data Days 2026

Don't miss out on Data Days, June 15 through August 7. Learn Fabric, Power BI, SQL, AI and more.

May Power BI Update Carousel

Power BI Monthly Update - May 2026

Check out the May 2026 Power BI update to learn about new features.

Power BI DataViz World Championships carousel

Power BI DataViz World Championships - June 2026

A new Power BI DataViz World Championship is coming this June! Don't miss out on submitting your entry.