Страницы: 1
RSS
В Power Query разделить текст по количеству символов, но оставить слова целыми
 
Привет всем. Хотел бы узнать как разделить текст по количеству знаков, но оставить слова целыми
Код
let
    Source = #table(1,{{"Есть вопросы? Спросите совета у старожилов или поделитесь опытом с новичками."}}),
    #"Split без учета целостности слова" = Table.ExpandListColumn(Table.TransformColumns(Source, {{"Column1", Splitter.SplitTextByRepeatedLengths(16), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Column1"),
    #"Как хотелось бы" = #table(1,{{"Есть вопросы? "},{"Спросите совета "},{"у старожилов или"},{" поделитесь "},{"опытом с "},{"новичками."}})
in
    #"Как хотелось бы"
 
Доброе время суток.
В первом приближении...
Код
let
    Source = #table(1,{{"Есть вопросы? Спросите совета у старожилов или поделитесь опытом с новичками."}}),
    splitText = Table.TransformColumns(Source, {"Column1", (item) =>
        let
            base = List.Accumulate(Text.Split(item, " "), [l = {}, s = ""], (a, n) =>
                let
                    next = if a[s] = "" then n else a[s] & " " & n
                in
                    if Text.Length(next) <= 16 then [l = a[l], s = next] else [l = a[l] & {a[s]}, s = n]
            )
        in
            base[l] & {base[s]}
    }),
    result = Table.ExpandListColumn(splitText, "Column1")
in
    result

Может через List.Generate будет и быстрее.
 
Андрей VG, большое спасибо! А как этим пользоваться? :D  В принципе, мне только и остается менять циферки в этом коде :)
С List.Generate будет тоже такое неприступное?
 
Цитата
Михаил Л написал:
А как этим пользоваться?
Например так Power Query: как перестать бояться функционального программирования и начать работать в расширенном редакторе запросов, КАК НА ЯЗЫКЕ M В POWER QUERY СОЗДАТЬ СПИСОК ИЗ НАИМЕНОВАНИЙ МЕСЯЦЕВ. ФУНКЦИЯ LIST.ACCUMULATE Источник: https://biprosto.ru/power-query/list-accumulate.html
Сейчас тёзка подтянется - толи ещё будет :)
Изменено: Андрей VG - 20.02.2020 21:53:38
 
Андрей VG, спасибо. Попробую понять
 
еще вариант
Код
let
    Source = 
        #table(1,{{"Есть вопросы? Спросите совета у старожилов или поделитесь опытом с новичками."}}),
    Split = 
        ((t,s,n) => 
        Table.TransformColumns(t, 
            {
                {
                 s, 
                 each let 
                    a =
                        Text.PositionOf(_," ",3), 
                    b = 
                        List.Generate(()=>
                            [i=List.PositionOf(a,n,0,(c,d)=>c>d)-1],
                            each [i]<>List.Count(a) and [i]>0,
                            each [i=List.PositionOf(a,n,0,(c,d)=>(c-a{[i]})>d)-1], 
                            each a{[i]}
                        ) 
                 in 
                    Splitter.SplitTextByPositions({0}&b)(_)
                }
            }
        ))(
            Source,"Column1",16
        ),
    Expand = Table.ExpandListColumn(Split,"Column1")
in
    Expand
 
Андрей Лящук, спасибо большое. На это интересно смотреть :)
(t,s,n) => ?
 
Цитата
Михаил Л написал:
?
Ещё до сих пор не изучено Спецификация языка Power Query M? Предпочитаете метод научного тыка? :)
Андрей Лящук, вы не находите, что " опытом с новичками" по длине равно 19 и как-то выбивается из вашей стратегии, чтобы число символов было меньше или равно заданному n (в примере ТС n = 16)?
Ну, и если входная фраза ""Есть_вопросы?_Спросите совета у старожилов или поделитесь_опытом с новичками", то ваш подход возвращает только одну строку без разбиений (что в общем-то логично с точки зрения стратегии, но вот логично ли с точки зрения ожидаемого результата ТС?).
Мой, правда, тоже косячит - первым разбиением возращает пустую строку :)
Изменено: Андрей VG - 21.02.2020 08:30:30
 
Андрей VG, добрый день!

Огромная просьба, покажите, пожалуйста, на примере двух вложенных пользовательских функций из Вашего решения к какому виду их можно привести для отладки.

Заранее спасибо.
 
quasarrr,
1.
Код
let
    // (item) =>
    item = "Есть вопросы? Спросите совета у старожилов или поделитесь опытом с новичками.",
    base = List.Accumulate(Text.Split(item, " "), [l = {}, s = ""], (a, n) =>
        let
            next = if a[s] = "" then n else a[s] & " " & n
        in
            if Text.Length(next) <= 16 then [l = a[l], s = next] else [l = a[l] & {a[s]}, s = n]
    ),
    return = base[l] & {base[s]}
in
    return

2.
Код
let
    // (a, n) =>
    a = [l = {"Есть вопросы?"}, s = "Спросите"],
    n = "совета",
    next = if a[s] = "" then n else a[s] & " " & n,
    return = if Text.Length(next) <= 16 then [l = a[l], s = next] else [l = a[l] & {a[s]}, s = n]
in
    return
Изменено: Андрей VG - 21.02.2020 09:20:22
 
Андрей VG,

Спасибо большое!
 
Михаил Л, прошу немножко уточнить задачу, если найдено место, по которому нужно делить строку, то в полученной подстроке количество символов должно быть <= 16, если в слове символов не более 16. Так? Далее следующее деление начинаем искать от остатка строки, после откусывания первого найденного. Так? Разделителем слов считаем только пробелы? Или что-то еще?
Изменено: PooHkrd - 21.02.2020 10:01:04
Вот горшок пустой, он предмет простой...
 
PooHkrd, хотелось бы в строке не более 16 знаков(пробел тоже считаем за знак). То что может быть слово длиной более 16 знаков я не предусмотрел (например, если не сложно, то оставить слово целым). Для примера 16 знаков, а так будет текст делиться знаков по 100.
Цитата
PooHkrd написал:
Далее следующее деление начинаем искать от остатка строки, после откусывания первого найденного
Да, так.
Разделитель только пробел. Даже не знаю что еще добавить в разделители. В принципе после точки, запятой, восклицательного и вопросительного знака должен присутствовать пробел.
Вариант Андрей VG  проблему решает, только сложно воспринимать
 
Цитата
Михаил Л написал:
Вариант  Андрей VG   проблему решает, только сложно воспринимать
Это понятно, просто самому охота мозги размять, как время появится.
Вот горшок пустой, он предмет простой...
 
Цитата
Андрей VG написал:
Предпочитаете метод научного тыка?
Честно говоря, что читай что не читай эту спецификацию в голове не укладывается и не откладывается.
По моему, с опытом решений задач приходит понимание. Был бы рядом наставник, который бы  делился знаниями, то изучение Power Query пошло бы быстрее. А так возле каждой ошибки ходишь вокруг да около и не знаешь что делать
 
исправленный вариант на List.Generate
Код
let
    Source = 
        #table(1,{{"Есть вопросы? Спросите совета у старожилов или поделитесь опытом с новичками."}}),
    Split = 
        (t,s,n) => 
        Table.ExpandListColumn(
            Table.TransformColumns(t, 
                {
                    {
                     s, 
                     each let 
                        a =
                            Text.PositionOf("  "&_&" "," ",3), 
                        b = 
                            List.Generate(
                                ()=> [i=1],
                                each [i]>0,
                                each [ j=List.PositionOf(a,n,0,(c,d)=>(c-a{[i]}-2)>=d)-1,
                                       i= if j=[i] then j+1 else j ], 
                                each a{[i]}-1
                            ) 
                     in 
                        List.RemoveLastN(
                            Splitter.SplitTextByPositions(b)(_),
                            (_)=> _=""
                        )
                    }
                }
            ),
            s
        ),
    Expand = 
        Split(
            Source,
            "Column1",
             16
        )
in
    Expand
 
Андрей Лящук, ,спасибо большое!
Страницы: 1
Наверх