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

Get Fabric Certified for FREE during AI Skills Fest. This week only. Secure your voucher now.

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
May Power BI Update Carousel

Power BI Monthly Update - May 2026

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

Fabric SQL PBI Data Days

Data Days 2026 coming soon!

Sign up to receive a private message when registration opens and key events begin.

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.