Хватит мучать List.Accumulate!

#АнатомияФункций – List.Accumulate, List.Skip



Всем привет!

Решил разобрать «интересный» подход к нахождению необходимого пункта по фрагменту ключевого текста (т.е. поиск по словарю с неполным соответствием).

Почему-то уже неоднократно вижу приматывание в этой ситуации решения от задачи по множественной замене в тексте. На входе примерно такой код:

let

f=(x)=>Text.Split(List.Accumulate(dict,x,(s,c)=>Text.Replace(s,c[Назначение платежа],c[Статья расходов])),"!"){1}?,

dict = List.Buffer(Table.ToRecords(Table.TransformColumns(Excel.CurrentWorkbook(){[Name="справочник"]}[Content],{"Статья расходов",(x)=>"!"&x&"!"}))),

from = Table.PromoteHeaders(Excel.CurrentWorkbook(){[Name="данные"]}[Content])[[Дата проведения],[Сумма в валюте счёта],[Назначение платежа]],

tr = Table.TransformColumns(from,{"Назначение платежа",Text.Lower}),

to = Table.TransformColumns(tr,{"Назначение платежа",f})

in

to


Который стоит превратить вот в такой:

let

f=(x)=>Text.Split(List.Accumulate(dict,[a=x,b=false],(s,c)=>if s[b] then s else if Text.Contains(s[a],c[Назначение платежа]) then [a=c[Статья расходов],b=true] else s)[a],"!"){1}?,



dict=List.Buffer(Table.ToRecords(Table.TransformColumns(Excel.CurrentWorkbook(){[Name="Таблица3"]}[Content], {"Статья расходов", (x)=>"!"&x&"!"}))),

from = Table.PromoteHeaders(Excel.CurrentWorkbook(){[Name="data"]}[Content])[[Дата проведения],[Сумма в валюте счёта],[Назначение платежа]],

tr = Table.TransformColumns(from,{"Назначение платежа",Text.Lower}),

to = Table.TransformColumns(tr,{"Назначение платежа",f})

in

to


А лучше вот в такой:

let

f=(x)=>[a=List.Accumulate(dict,[a=x,b=false],(s,c)=>if s[b] then s else if Text.Contains(s[a],c[Назначение платежа]) then [a=c[Статья расходов],b=true] else s),

b=if a[b] then a[a] else null][b],

dict=List.Buffer(Table.ToRecords(Excel.CurrentWorkbook(){[Name="Таблица3"]}[Content])),

from = Table.PromoteHeaders(Excel.CurrentWorkbook(){[Name="data"]}[Content])[[Дата проведения],[Сумма в валюте счёта],[Назначение платежа]],

tr = Table.TransformColumns(from,{"Назначение платежа",Text.Lower}),

to = Table.TransformColumns(tr,{"Назначение платежа",f})

in

to




А ещё лучше… оставить в покое несчастный аккумулятор и решать задачи функциями, которые для них предназначены:

let

f=(x)=>List.Skip(dict,(y)=>not Text.Contains(x,y{0})){0}?{1}?,



dict=List.Buffer(Table.ToList(Excel.CurrentWorkbook(){[Name="Таблица3"]}[Content],(x)=>x)),

from = Table.PromoteHeaders(Excel.CurrentWorkbook(){[Name="data"]}[Content])[[Дата проведения],[Сумма в валюте счёта],[Назначение платежа]],

tr = Table.TransformColumns(from,{"Назначение платежа",Text.Lower}),

to = Table.TransformColumns(tr,{"Назначение платежа",f})

in

to




Что тут к чему и порция бомбления уже на Дзене

Файл-исходник на sponsr

Если повезёт, то и ютуб подтянется



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



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

Всех благ!

@buchlotnik