Цитата |
---|
PooHkrd написал: функции создаются когда используются в дальнейшем неоднократно |
Встроенные функции в PQ часто работают как итератор, применяющий к элементам какого-то набора (строкам таблицы, элементам списка, полям записи) заданную
функцию преобразования. Поэтому мы ее все равно всегда пишем, вопрос только в том, где - определяем отдельным шагом или внутри итератора.
Скрытый текст |
---|
Например, функция Table.AddColumn имеет 4 аргумента: таблица, название столбца, функция-генератор, тип столбца. И работает де-факто примерно так: берем таблицу как список записей, к каждой записи (итерация) добавляем новое поле, которое получаем путем вычисления какого-то выражения. Чтобы вычисляемое выражение могло использовать данные других полей этой записи (читай, других столбцов в этой строке таблицы), используется функция, в которую по умолчанию передается текущая запись, когда мы используем слово each. Это слово в данном случае - шорткод записи вот такой функции (_ as record)=>, при этом идентификатор "_" можно опускать при обращении к полям (они же столбцы): (_)=>_[Column1] эквивалентно each [Column1]. В общем, each - это замена обращения к текущему элементу итерации, выполняемой функцией Table.AddColumn. Тот же принцип действует практически для всех итераторов, у которых есть аргумент в виде функции - при использовании each она получит на вход текущий элемент итератора, который можно опустить, а можно не опускать и обращаться к нему как "_". |
Вот эта функция
Код |
---|
= (str, rec)=>Record.TransformFields(rec, List.Transform(lstFields, each {_, (field)=>if field = "null" then null else Text.Contains(str, field, Comparer.OrdinalIgnoreCase)})) |
может не создаваться отдельным шагом, и добавление столбца может быть записано как
Код |
---|
= Table.AddColumn(ExpandStrings, "Custom", (_)=> Record.TransformFields(_[Column1], List.Transform(lstFields, (el)=>{el, (field)=>if field = "null" then null else Text.Contains(_[String], field, Comparer.OrdinalIgnoreCase)})))
'или
= Table.AddColumn(ExpandStrings, "Custom", each Record.TransformFields([Column1], List.Transform(lstFields, (el)=>{el, (field)=>if field = "null" then null else Text.Contains([String], field, Comparer.OrdinalIgnoreCase)}))) |
Но мне так было удобнее для отладки. С точки зрения производительности разницы нет - функция в М не будет вычисляться до тех пор, пока ее не будут использовать.