List.PositionOf – или ПОИСКПОЗ на стероидах #АнатомияФункций - List.PositionOf
Всем привет! При решении задач периодически возникает необходимость найти позицию определённого значения в списке, для этого разумно использовать List.PositionOf. И на этом можно бы было завершить пост, если бы не одно обстоятельство – это функция четырёх аргументов, а значит нас ждёт много вкусного ))) Поехали: List.PositionOf(list as list, value as any, optional occurrence as nullable number, optional equationCriteria as any) as any
Обязательные аргументы: list – сам список value – искомое значение
Необязательные аргументы: occurrence – «вхождение» - принимает варианты Occurrence.First, Occurrence.Last, Occurrence.All – т.е. первое, последнее или все equationCriteria – критерий сравнения – сюда можно написать Comparer или собственную функцию от двух аргументов (current,value)=> - обратите внимание на порядок – сначала current – проверяемый элемент списка, затем value – наше искомое значение
Ну и пример, ниже разберем по шагам:
Код
let
a = List.PositionOf({1..10},5), //4
b = List.PositionOf({"a".."z"},"d"), //3
c = List.PositionOf({1..10},11), //-1 - значение не найдено
d = List.PositionOf({1,2,null,3,4,null,5},null), //2
e = List.PositionOf({1,2,null,3,4,null,5},null,Occurrence.First),//2
f = List.PositionOf({1,2,null,3,4,null,5},null,Occurrence.Last), //5
g = List.PositionOf({1,2,null,3,4,null,5},null,Occurrence.All), //{2,5}
h = List.PositionOf({1,2,null,3,4,null,5},null,Occurrence.First,(c,v)=>c<>v),//0
i = List.PositionOf({1,2,null,3,4,null,5},null,Occurrence.Last,(c,v)=>c<>v),//6
j = List.PositionOf({1,2,null,3,4,null,5},null,Occurrence.All,(c,v)=>c<>v),//{0,1,3,4,6}
k = List.PositionOf({1..5},3,Occurrence.All,(c,v)=>c<v), //{0,1}
l = List.PositionOf({1..5},3,Occurrence.All,(c,v)=>c>v), //{3,4}
m = List.PositionOf({1,2,null,3,4,null,5},3,Occurrence.All,(c,v)=>if c is null then false else c>v),//{4,6}
n = List.PositionOf({"a".."z"},"D",Occurrence.All,Comparer.OrdinalIgnoreCase) //3
in
n
Шаги a -d – простое использование с двумя обязательными аргументами a – ищем и находим число в списке, обращаем внимание, что нумерация элементов идёт с нуля b – то же самое, но для текста c – запоминаем, что в случае, если элемент не найден, вернётся не ошибка, а значение -1 d – искать можно и null
Шаги e – g – добавляем Occurrence e – сравните с шагом d – понимаем, что по умолчанию используется Occurrence.First – т.е. ищется первое вхождение f – Occurrence.Last даст нам последнее вхождение g – Occurrence.All вернёт список всех вхождений значения
Шаги h – n – подключаем тяжёлую артиллерию – четвертый аргумент))) Что делать, если мы не знаем конкретное значение, а просто ищем первый/последний непустой элемент? Смотрим шаги h – j – в списке ищем null, но с функцией (c,v)=>c<>v – т.е. не равно null k,l - аналогично можно искать значения меньшие или большие заданного m – функция может быть сложной – в данном случае в списке есть null и их невозможно сравнить с числом, поэтому для любого null возвращаем false, а остальные значения сравниваем с искомым n – ну и вариант с текстами – в четвертом аргументе, например, можно прописать условие игнорирования регистра
Как-то так – очередная функция, вся мощь которой проявляется в необязательных аргументах. Экспериментируйте!
Собрать данные по заданной маске с листов и сформировать сводную таблицу на отдельном листе, Собрать данные по заданной маске с листов и сформировать сводную таблицу на отдельном листе
Собрать данные по заданной маске с листов и сформировать сводную таблицу на отдельном листе, Собрать данные по заданной маске с листов и сформировать сводную таблицу на отдельном листе
Ольга Аба, test upd. + listSort в tableGroup_step2 upd2. - тоже не то, криво собирает в некоторых ситуациях upd3. группировка по : артикул -> номер -> снова артикул ->..
let
Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
tableTransformRows =
Table.TransformRows(
Source,
( x ) =>
Record.TransformFields(
x,
{
"Column2",
( y ) =>
if y = null then x[ Column1 ]
else if x[ Column1 ] = "Текст4" then Text.Combine( { x[ Column1 ], y }, "||" )
else y
}
)
),
tableFromRecords = Table.FromRecords( tableTransformRows )
in
tableFromRecords
или
Код
let
Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
tableToRecords = Table.ToRecords( Source ),
listTransform =
List.Transform(
tableToRecords,
( x ) =>
Record.TransformFields(
x,
{
"Column2",
( y ) =>
if y = null then x[ Column1 ]
else if x[ Column1 ] = "Текст4" then Text.Combine( { x[ Column1 ], y }, "||" )
else y
}
)
),
tableFromRecords = Table.FromRecords( listTransform )
in
tableFromRecords
ну и нужно тестировать, какой объем таблицы ? возможно проще будет в некоторых ситуациях: 1 создать новый столбец, 2 удалить старый, 3 переименовать новый, 4 отсортировать столбцы как были изначально