Списки против записей, генератор против рекурсии или коротко не значит быстро
#АнатомияФункций – рекурсия, List.Generate
Всем привет!
Был запрос на разбор сложных задач с «эволюцией» решений. По этому поводу:
Исходное
Чутка поправленное
С радикально изменённой логикой:
И немножко допиленное:
Ну а что тут к чему смотрите, как всегда, на Ютубе
Лайк, коммент, подписка приветствуются )))
Поддержка канала
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций – рекурсия, 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