Списки против записей, генератор против рекурсии или коротко не значит быстро

#АнатомияФункций – рекурсия, List.Generate



Всем привет!

Был запрос на разбор сложных задач с «эволюцией» решений. По этому поводу:

Исходное

let

f=(from,to)=>[gen=List.Generate(()=>[s=from,e=List.Min({to,Date.EndOfMonth(from)})],

(x)=>x[s]<to,

(x)=>[s=Date.StartOfMonth(Date.AddMonths(x[s],1)),e=List.Min({to,Date.EndOfMonth(s)})],

(x)=>Record.FromList({Duration.TotalHours(x[e]-x[s])},{DateTime.ToText(x[s],"yyyyMM")})),

tbl=Table.FromRecords({[Начало=from,Окончание=to]&Record.Combine(gen)})][tbl],

from = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],

lst = Table.ToList(from,(x)=>f(x{0},x{1})),

to = Table.Combine(lst)

in

to


Чутка поправленное

let

f=(x,y,z)=>if Date.EndOfMonth(x)>y

then Record.AddField(z,DateTime.ToText(x,"yyyyMM"),Duration.TotalHours(y-x))

else @f(Date.StartOfMonth(Date.AddMonths(x,1)),y,Record.AddField(z,DateTime.ToText(x,"yyyyMM"),Duration.TotalHours(Date.EndOfMonth(x)-x))),



from = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],

lst = List.Buffer(Table.ToList(from,(x)=>f(x{0},x{1},[Начало=x{0},Окончание=x{1}]))),

nms = List.Distinct(List.Combine(List.Transform(lst,Record.FieldNames))),

to = Table.FromRecords(lst,nms,MissingField.UseNull)

in

to


С радикально изменённой логикой:

let



f=(x)=>[a=g(x{0},x{1},{}),

b=List.PositionOf(tr,DateTime.ToText(x{0},"yyyyMM")),

c=x&List.ReplaceRange(nul,b,List.Count(a),a)][c],

g=(x,y,z)=>if Date.EndOfMonth(x)>y

then z&{Duration.TotalHours(y-x)}

else @g(Date.StartOfMonth(Date.AddMonths(x,1)),y,z&{Duration.TotalHours(Date.EndOfMonth(x)-x)}),



from = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],

ot = Date.StartOfMonth(List.Min(from[Начало работ])),

do = List.Max(from[Завершение работ]),

gen = List.Generate(()=>ot,(x)=>x<do,(x)=>Date.AddMonths(x,1)),

tr = List.Buffer(List.Transform(gen,(x)=>DateTime.ToText(x,"yyyyMM"))),

nul = List.Buffer(List.Repeat({null},List.Count(tr))),



to = Table.FromList(Table.ToList(from,f),(x)=>x,Table.ColumnNames(from)&tr)

in

to


И немножко допиленное:

let



f=(x)=>x&List.Repeat({null},List.PositionOf(tr,DateTime.ToText(x{0},"yyyyMM")))&g(x{0},x{1},{}),

g=(x,y,z)=>if Date.EndOfMonth(x)>y

then z&{Duration.TotalHours(y-x)}

else @g(Date.StartOfMonth(Date.AddMonths(x,1)),y,z&{Duration.TotalHours(Date.EndOfMonth(x)-x)}),

h=(x,y,z)=>if x>y then z else @h(Date.AddMonths(x,1),y,z&{x}),



from = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],

ot = Date.StartOfMonth(List.Min(from[Начало работ])),

do = List.Max(from[Завершение работ]),

tr = List.Buffer(List.Transform(h(ot,do,{}),(x)=>DateTime.ToText(x,"yyyyMM"))),

to = Table.FromList(Table.ToList(from,f),(x)=>x,Table.ColumnNames(from)&tr)

in

to


Ну а что тут к чему смотрите, как всегда, на Ютубе



Лайк, коммент, подписка приветствуются )))

Поддержка канала



Надеюсь, было полезно.

Всех благ!

@buchlotnik