Фильтрация списка по списку через словарь и Splitter

#АнатомияФункций - Record.FieldOrDefault, Splitter.SplitTextByRanges



Всем привет!

Итак, задачка – «отфильтровать один список по частичным совпадениям начала строк со вторым».

Делов-то:

let

lst = Excel.CurrentWorkbook(){[Name="tsrc"]}[Content][col],

dict = List.Buffer(Excel.CurrentWorkbook(){[Name="tmatch"]}[Content][match]),

to = List.Select(lst,(x)=>List.Contains(dict,x,(y)=>Text.StartsWith(x,y)))

in

to




Только проблема… медленно это. И вот приходит такой Андрей (m) и выкатывает:

let

lst = List.Buffer(Excel.CurrentWorkbook(){[Name="tsrc"]}[Content][col]),

dict = List.Buffer(Excel.CurrentWorkbook(){[Name="tmatch"]}[Content][match]),

to = List.Transform(List.PositionOfAny(lst,dict,Occurrence.All,(c,v)=>Text.StartsWith(c,v)),(x)=>lst{x})

in

to




А я говорю – да нет, тогда уж вот:

let

lst = List.Buffer(Excel.CurrentWorkbook(){[Name="tsrc"]}[Content][col]),

dict = List.Buffer(Excel.CurrentWorkbook(){[Name="tmatch"]}[Content][match]),

to = List.Transform(List.PositionOfAny(lst,dict,Occurrence.All,Text.StartsWith),(x)=>lst{x})

in

to




А тут ещё Игорь (CubRoot) приходит, говорит вот так надо:

let

lst = Excel.CurrentWorkbook(){[Name="tsrc"]}[Content][col],

dict = List.Buffer(Excel.CurrentWorkbook(){[Name="tmatch"]}[Content][match]),

to = List.Select(lst,(x)=>Splitter.SplitTextByAnyDelimiter(dict)(x){0}="")

in

to




А я такой – блин, да нет же – вот так надо:

let

lst = Excel.CurrentWorkbook(){[Name="tsrc"]}[Content][col],

dic = Excel.CurrentWorkbook(){[Name="tmatch"]}[Content][match],

len = List.Buffer(List.Distinct(List.Transform(dic,Text.Length))),

dict = Record.FromList(List.Repeat({true},List.Count(dic)),dic),

f=(x)=>List.AnyTrue(List.Transform(len,(y)=>Record.FieldOrDefault(dict,Text.Start(x,y)))),

to = List.Select(lst,f)

in

to




... а сам думаю, но ведь со сплиттером-то и правда вкуснее:

let

lst = Excel.CurrentWorkbook(){[Name="tsrc"]}[Content][col],

dic = Excel.CurrentWorkbook(){[Name="tmatch"]}[Content][match],

len = List.Buffer(List.Distinct(List.Transform(dic,(x)=>{0,Text.Length(x)}))),

dict = Record.FromList(List.Repeat({true},List.Count(dic)),dic),

f=(x)=>List.AnyTrue(List.Transform(Splitter.SplitTextByRanges(len)(x),(y)=>Record.FieldOrDefault(dict,y))),

to = List.Select(lst,f)

in

to




И вот так долго ли коротко ли скорость выполнения была приподнята в 15 раз )))

А как оно так – смотрим на дзене

Исходники с бонусными вариантами на sponsr

Сектанты могут верить, что и на ютубе появится



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



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

Всех благ!

@buchlotnik