-
Notifications
You must be signed in to change notification settings - Fork 3
/
camelCaseToSnake
38 lines (35 loc) · 1.81 KB
/
camelCaseToSnake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
(t as table) =>
let
// Function to check if a header is already in snake_case
IsSnakeCase = (header as text) as logical =>
Text.Contains(header, "_") and
Text.Lower(header) = header and
not List.AnyTrue(List.Transform({"A".."Z"}, each Text.Contains(header, _))),
// Function to check if a header is a single word without mixed letters and numbers
IsSingleWord = (header as text) as logical =>
not Text.Contains(header, " ") and
not List.AnyTrue(List.Transform({"A".."Z"}, each Text.Contains(header, _))) and
not List.AnyTrue(List.Transform({"0".."9"}, each Text.Contains(header, _))),
// Function to transform camelCase or mixed words to snake_case
ToSnakeCase = (header as text) as text =>
let
// Find the positions of capital letters using Occurrence.All
capitalPositions = Text.PositionOfAny(header, {"A".."Z"}, Occurrence.All),
// Find the positions of numbers using Occurrence.All
numberPositions = Text.PositionOfAny(header, {"0".."9"}, Occurrence.All),
// Combine capital and number positions, including the start position
positions = List.Sort(List.Distinct(List.Combine({{0}, capitalPositions, numberPositions}))),
// Split the text at the positions
splitWords = List.Transform(Splitter.SplitTextByPositions(positions)(header), each Text.Lower(_)),
// Combine the words with underscores
finalResult = Text.Combine(splitWords, "_"),
finalResult2 = Text.Replace(finalResult," ","")
in
finalResult2,
// Apply the transformation only to headers that need it
Source = Table.TransformColumnNames(
t,
each if IsSnakeCase(_) or IsSingleWord(_) then _ else ToSnakeCase(_)
)
in
Source