Страницы: 1
RSS
определить вхождение подстрок для большой таблицы с помощью PQ, есть столбец с текстовыми строками
 
1. есть таблица шириной в столбец с текстовыми значениями, каждое содержит  от 1го до 10 СЛОВ через разделители (пробелы, скобки, запятые, кавычки и т.п.): например
AAA "BB" (CCC)
CCC BB DDD

2. есть таблица шириной 20 столбцов, в каждой строке  - набор отдельных СЛОВ:
AAA; BB;  
AAA; CCC; BB; null

как заполнить таблицу, в которой будут результат: содержится в столбце (1) СЛОВО таблицы (2) : например
true; true
false; true; false

т.е. скрестить Text.Contains и Join
PS: я кроме ошибки компилятора ничего получить не могу (((
 
приложите файл-пример.
и поясните,
- сопоставлять надо построчно?
- наличие разделителей в первой таблице играет роль? Если да, то их перечень нужен.
- Совпадение полное или частичное?
- Кавычки и прочие символы релевантны или нет?
- что делаем с null?
- регистр символов учитывается?

Почему
CCC BB DDD  ==> AAA; CCC; BB; null  ==> false; true; false , а не false; true; true
F1 творит чудеса
 
построчно, разделители игнорируем, вхождение СЛОВА в СТРОКУ полное,
null дает результат null, регистр не важен

в идеале - вот так (приложил)
 
ловите. В идеальном этом варианте нетривиально решилось :)
только у вас null это текстовое значение, исправьте там в коде, если оно пустое на самом деле
F1 творит чудеса
 
Цитата
Максим Зеленский написал:
нетривиально решилось
изумительно решилось!  именно то, что надо  8)
остался маленький вопрос - как средствами PQ "свернуть" столбцы WORD_n логическим AND, игнорируя null ?
т.е. получить столбец "Результат" = AND(WORD1, ... WORD15), не учитывая столбцы содержащие null

EXCEL игнорирует пустые ячейки по умолчанию, а вот в PQ оператор AND не работает как надо  - выдает либо FALSE, либо null :(  
 
Цитата
VladimirVSh написал:
как средствами PQ "свернуть" столбцы WORD_n логическим AND, игнорируя null ?
Вы не обидитесь, если я скажу, что если задача была изначально получить вот такой результат, то она решается проще и по-другому?  :evil:
Считает верно, так как null and true в рамках языка М будет равно null.

Предпоследним шагом в моем файле добавьте пользовательский столбец с такой формулой:
Код
List.AnyTrue(Record.FieldValues([Custom]))
F1 творит чудеса
 
Цитата
Максим Зеленский написал: Вы не обидитесь
Нисколько! когда-то классики настаивали что надо "... учить, пороть всурьез"  :D
Мне именно эта позиция и была нужна: алгоритм соединения таблиц с использованием функции.

Про "List.AnyTrue" - каюсь, не со всеми функциями знаком! В голову не приходило, что работу с диапазонами заменят на отдельные функции
 
Цитата
VladimirVSh написал:
работу с диапазонами заменят на отдельные функции
В PQ нет диапазонов как в Excel. Есть значения, функции и выражения, а есть таблицы, списки, записи и их сочетания. Столбец таблицы = список, строка таблицы = запись, таблица может быть понята как список записей, и так далее. В общем, это не совсем Excel :)
F1 творит чудеса
 
Максим Зеленский, я бы даже сказал, что это совсем не Excel.
Максим, очень красивое решение, скажите, чем вы руководствовались, когда создавали пользовательскую функцию в ходе решения? Я из прошлого опыта программирования привык, что функции создаются когда используются в дальнейшем неоднократно. Либо для организации рекурсивного к ней обращения. А здесь без неё было никак?
Изменено: PooHkrd - 29.04.2022 22:03:47
Вот горшок пустой, он предмет простой...
 
Цитата
PooHkrd написал:
функции создаются когда используются в дальнейшем неоднократно
Встроенные функции в PQ часто работают как итератор, применяющий к элементам какого-то набора (строкам таблицы, элементам списка, полям записи) заданную функцию преобразования. Поэтому мы ее все равно всегда пишем, вопрос только в том, где - определяем отдельным шагом или внутри итератора.
Скрытый текст
Вот эта функция
Код
= (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)})))

Но мне так было удобнее для отладки. С точки зрения производительности разницы нет - функция в М не будет вычисляться до тех пор, пока ее не будут использовать.
Изменено: Максим Зеленский - 20.06.2017 13:41:39
F1 творит чудеса
 
Цитата
Максим Зеленский написал:
то она решается проще и по-другому?
если не затруднит - как можно проще решить эту задачу?  
я понял так, что если не нужно определять вхождение каждого СЛОВО, то решение будет намного проще? видимо не для меня  :cry:  
 
VladimirVSh, так озвучьте конечную цель, без предположений о промежуточных этапах, если они не нужны в дальнейшем.

Я понял задачу так: определить, содержит ли строка из таблицы СТРОКИ любое из слов, содержащихся в строке таблице СЛОВА (для каждой строки), и вернуть номера строк из таблицы СЛОВА.
Так? Или не так?
F1 творит чудеса
 
Цитата
Максим Зеленский написал:
так озвучьте конечную цель
определить, содержит ли строка из таблицы СТРОКИ все слова, содержащихся в строке таблице СЛОВА (для каждой строки), и вернуть номера строк из таблицы СЛОВА
т.е. определить номера строк таблицы СТРОКИ, в которых содержатся  все слова в строке таблицы СЛОВА

PS: Для первой задачи нужна была промежуточная таблица для анализа. Теперь похожая задача, но для нее нужно полное "вложение"  слов в строку  
 
Примерно так можно
F1 творит чудеса
 
Спасибо! утащил думать  :)  
Страницы: 1
Наверх