Skip to content

Commit

Permalink
Merge pull request #7 from AlexisOlson/Text
Browse files Browse the repository at this point in the history
New Text functions
  • Loading branch information
OscarValerock authored Apr 18, 2024
2 parents 71d811f + 6b2f6be commit 6b87e25
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 0 deletions.
48 changes: 48 additions & 0 deletions Functions/Text/Text.Collapse.pq
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
let
// Define metadata for the function, describing its purpose and usage.
metaDocumentation = type function (
txt as (type text meta [
Documentation.FieldCaption = "The text to search"
]),
characters as (type text meta [
Documentation.FieldCaption = "Character(s) to collapse"
]),
optional seperator as (type text meta [
Documentation.FieldCaption = "Seperator to use in final result"
])
) as text meta [
Documentation.Name = "Text.Collapse",
Documentation.Author = "Alexis Olson",
Documentation.LongDescription =
// This is the description of the documentation, it only accepts a handful of HTML tags for formatting.
"
Collapses multiple characters into a single seperator.
<p>See the illustrative examples listed below.</p>
<li><b>Author: </b>Alexis Olson</li>
<li><b>LinkedIn: </b>https://www.linkedin.com/in/alexis-olson-81726818/</li>
",
Documentation.Examples = {
[
Description = " Simple usage is similar to an inner and outer trim. ",
Code = " Text.Collapse(""--a----b--c---d---"", ""-"") ",
Result = " a-b-c-d "
],
[
Description = " Multiple characters can be collapsed and the result combined using a different separator. ",
Code = " Text.Collapse(""[(a-..-b).-.-.-.((c-..-d))]"", ""[(-.)]"", "" <=> "") ",
Result = " a <=> b <=> c <=> d "
]
}
],
myFunction =
(txt as text, characters as text, optional seperator as text) as text =>
let
Split = Text.SplitAny(txt, characters),
RemoveEmpty = List.Select(Split, each _ <> null and _ <> ""),
Seperator = seperator ?? Text.Start(characters, 1),
Result = Text.Combine(RemoveEmpty, Seperator)
in
Result
in
// Apply the function metadata to myFunction.
Value.ReplaceType(myFunction, metaDocumentation)
51 changes: 51 additions & 0 deletions Functions/Text/Text.ContainsAll.pq
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
let
// Define metadata for the function, describing its purpose and usage.
metaDocumentation = type function (
txt as (type text meta [
Documentation.FieldCaption = "The text to search"
]),
substrings as (type {text} meta [
Documentation.FieldCaption = "A list of substrings to search for"
]),
optional comparer as (type function meta [
Documentation.FieldCaption = "Comparer function to pass into Text.Contains"
])
) as logical meta [
Documentation.Name = "Text.ContainsAll",
Documentation.Author = "Alexis Olson",
Documentation.LongDescription =
// This is the description of the documentation, it only accepts a handful of HTML tags for formatting.
"
Checks whether the input text contains all of the substrings from the input list.
<p>Returns true if all of the substrings are found.</p>
<li><b>Author: </b>Alexis Olson</li>
<li><b>LinkedIn: </b>https://www.linkedin.com/in/alexis-olson-81726818/</li>
",
Documentation.Examples = {
[
Description = " Check if a sentence is a pangram (contains all letters of the alphabet). ",
Code = " Text.ContainsAll(""The quick brown fox jumps over the lazy dog."", {""a""..""z""}) ",
Result = " TRUE "
],
[
Description = " By default, comparison is case-sensitive and the following has an S but no s. ",
Code = " Text.ContainsAny(""Sphinx of black quartz, judge my vow."", {""a""..""z""}) ",
Result = " FALSE "
],
[
Description = " Comparison can be done using a case-insenitive comparer. ",
Code = " Text.ContainsAny(""Sphinx of black quartz, judge my vow."", {""a""..""z""}, Comparer.OrdinalIgnoreCase ) ",
Result = " TRUE "
]
}
],
myFunction =
(txt as text, substrings as list, optional comparer as function) as logical =>
let
Matches = List.Select(substrings, (substr) => Text.Contains(txt, substr, comparer)),
Result = (substrings = Matches) // All substrings are matched
in
Result
in
// Apply the function metadata to myFunction.
Value.ReplaceType(myFunction, metaDocumentation)
51 changes: 51 additions & 0 deletions Functions/Text/Text.ContainsAny.pq
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
let
// Define metadata for the function, describing its purpose and usage.
metaDocumentation = type function (
txt as (type text meta [
Documentation.FieldCaption = "The text to search"
]),
substrings as (type {text} meta [
Documentation.FieldCaption = "A list of substrings to search for"
]),
optional comparer as (type function meta [
Documentation.FieldCaption = "Comparer function to pass into Text.Contains"
])
) as logical meta [
Documentation.Name = "Text.ContainsAny",
Documentation.Author = "Alexis Olson",
Documentation.LongDescription =
// This is the description of the documentation, it only accepts a handful of HTML tags for formatting.
"
Checks whether the input text contains any of the substrings from the input list.
<p>Returns true if any of the substrings are found.</p>
<li><b>Author: </b>Alexis Olson</li>
<li><b>LinkedIn: </b>https://www.linkedin.com/in/alexis-olson-81726818/</li>
",
Documentation.Examples = {
[
Description = " Check if a sentence is a pangram. ",
Code = " Text.ContainsAll(""Hello World!"", {""and"", ""or""}) ",
Result = " TRUE "
],
[
Description = " By default, comparison is case-sensitive. ",
Code = " Text.ContainsAny(""Hello World!"", {""hello"", ""world""}) ",
Result = " FALSE "
],
[
Description = " Comparison can be done using a case-insenitive comparer. ",
Code = " Text.ContainsAny(""Hello World!"", {""hello"", ""kitty""}, Comparer.OrdinalIgnoreCase ) ",
Result = " TRUE "
]
}
],
myFunction =
(txt as text, substrings as list, optional comparer as function) as logical =>
let
Matches = List.Select(substrings, (substr) => Text.Contains(txt, substr, comparer)),
Result = not List.IsEmpty(Matches) // At least one substring is matched
in
Result
in
// Apply the function metadata to myFunction.
Value.ReplaceType(myFunction, metaDocumentation)
34 changes: 34 additions & 0 deletions Functions/Text/Text.ReplaceMany.pq
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
let
// Define metadata for the function, describing its purpose and usage.
metaDocumentation = type function (
txt as (type text meta [
Documentation.FieldCaption = "Text to modify"
]),
replacements as (type {text} meta [
Documentation.FieldCaption = "List of {old, new} text pairs"
])
) as text meta [
Documentation.Name = "Text.ReplaceMany",
Documentation.Author = "Alexis Olson",
Documentation.LongDescription =
// This is the description of the documentation, it only accepts a handful of HTML tags for formatting.
"
Performs the given replacements given by the list parameter in that order.
<p>The replacement list must contain text pairs where each pair is an old value and new value.</p>
<li><b>Author: </b>Alexis Olson</li>
<li><b>LinkedIn: </b>https://www.linkedin.com/in/alexis-olson-81726818/</li>
",
Documentation.Examples = {
[
Description = " Make three substitutions: š -> sh, Č -> Ch, and ž -> zh ",
Code = "Text.ReplaceMany(""Boštjan Černež"", {{""š"", ""sh""}, {""Č"", ""Ch""}, {""ž"", ""zh""}})",
Result = "Boshtjan Chernezh"
]
}
],
myFunction =
(txt as text, replacements as list) as text =>
List.Accumulate(replacements, txt, (s, c) => Text.Replace(s, c{0}, c{1}))
in
// Apply the function metadata to myFunction.
Value.ReplaceType(myFunction, metaDocumentation)
5 changes: 5 additions & 0 deletions M.pq
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ let
Json.Document = Json.Document,
Json.FromValue = Json.FromValue,
Lines.FromBinary = Lines.FromBinary,
List.Accumulate = List.Accumulate,
List.Average = List.Average,
List.Combine = List.Combine,
List.Count = List.Count,
Expand All @@ -122,6 +123,7 @@ let
List.Product = List.Product,
List.RemoveItems = List.RemoveItems,
List.RemoveNulls = List.RemoveNulls,
List.Select = List.Select,
List.StandardDeviation = List.StandardDeviation,
List.Sum = List.Sum,
List.Transform = List.Transform,
Expand Down Expand Up @@ -162,9 +164,12 @@ let
Table.TransformColumns = Table.TransformColumns,
Text.BeforeDelimiter = Text.BeforeDelimiter,
Text.Combine = Text.Combine,
Text.Contains = Text.Contains,
Text.From = Text.From,
Text.Repeat = Text.Repeat,
Text.Replace = Text.Replace,
Text.SplitAny = Text.SplitAny,
Text.Start = Text.Start,
Text.ToBinary = Text.ToBinary,
Text.Type = Text.Type,
Time.Hour = Time.Hour,
Expand Down
4 changes: 4 additions & 0 deletions M_Creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
'microsoft.com',
'odata.nextLink',
'Table.ToM',
'Text.Collapse',
'Text.ContainsAll',
'Text.ContainsAny',
'Text.ReplaceMany',
'Web.Contents', #Unfortunately adding this function to the M code will create a dynamic error :(
'www.linkedin',
'youtu.be',
Expand Down

0 comments on commit 6b87e25

Please sign in to comment.