This time we’re going bigger than ever. Fabric, Power BI, SQL, AI and more. We're covering it all. You won't want to miss it.
Learn moreGet Fabric Certified for FREE during AI Skills Fest. This week only. Secure your voucher now.
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
bucketa 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
Solved! Go to Solution.
@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
@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
Hi
Another solution
= List.Transform(
{1..List.Count(alist)},
(i)=> List.Transform(
List.Numbers(List.Max({0, i-window}), window),
each alist{_}))
Stéphane
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, {})
@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
especially like the accumulate version.
@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
Thaanks all, that's enough to be going on with i shall go through them all.
@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
Check out the May 2026 Power BI update to learn about new features.
Sign up to receive a private message when registration opens and key events begin.
| User | Count |
|---|---|
| 5 | |
| 4 | |
| 3 | |
| 2 | |
| 1 |
| User | Count |
|---|---|
| 11 | |
| 11 | |
| 5 | |
| 4 | |
| 3 |