update docs
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
name = "GeneralUtils"
|
name = "GeneralUtils"
|
||||||
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
authors = ["tonaerospace <tonaerospace.etc@gmail.com>"]
|
authors = ["tonaerospace <tonaerospace.etc@gmail.com>"]
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|||||||
+341
-83
@@ -5,7 +5,7 @@ export noNegative!, randomWithProb, randomChoiceWithProb, findIndex, limitvalue,
|
|||||||
replaceLessThan, replaceBetween, cartesianAssign!, sumAlongDim3, matMul3Dto3DmanyTo1batch,
|
replaceLessThan, replaceBetween, cartesianAssign!, sumAlongDim3, matMul3Dto3DmanyTo1batch,
|
||||||
matMul_3Dto4D_batchwise, isNotEqual, linearToCartesian, vectorMax, findMax,
|
matMul_3Dto4D_batchwise, isNotEqual, linearToCartesian, vectorMax, findMax,
|
||||||
multiply_last, multiplyRandomElements, replaceElements, replaceElements!, isBetween,
|
multiply_last, multiplyRandomElements, replaceElements, replaceElements!, isBetween,
|
||||||
isLess, allTrue, getStringBetweenCharacters, JSON3read_stringKey, mkDictPath!,
|
isLess, allTrue, getStringBetweenCharacters, mkDictPath!,
|
||||||
getDictPath, detectKeywordVariation, textToDict, dictify, ordereddictify
|
getDictPath, detectKeywordVariation, textToDict, dictify, ordereddictify
|
||||||
|
|
||||||
using JSON, DataStructures, Distributions, Random, Dates, UUIDs, DataFrames, CSV
|
using JSON, DataStructures, Distributions, Random, Dates, UUIDs, DataFrames, CSV
|
||||||
@@ -152,12 +152,32 @@ end
|
|||||||
|
|
||||||
""" read_textfile_by_index(folder_path::String, read_file_number::Integer=1)
|
""" read_textfile_by_index(folder_path::String, read_file_number::Integer=1)
|
||||||
|
|
||||||
with multiple text file in a folder,
|
# What it does
|
||||||
this function read x_th text file in a folder (filename is sorted by OS)
|
- Reads the x-th text file from a folder, where files are listed by the OS
|
||||||
|
without explicit sorting. Returns the file number, filename, and content.
|
||||||
|
|
||||||
# Example
|
# Arguments
|
||||||
utils.read_textfile_by_index(cleaned_data_path, 2)
|
- `folder_path::String`
|
||||||
read 2nd txt file in a folder
|
Path to the folder containing text files.
|
||||||
|
- `read_file_number::Integer=1`
|
||||||
|
Which file to read (1-based index). Defaults to the first file.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- A tuple of `(file_number::Integer, filename::String, content)` where:
|
||||||
|
- `file_number` is the index of the file that was read
|
||||||
|
- `filename` is the actual filename string
|
||||||
|
- `content` is a vector of lines from the file (or `nothing` if error)
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
- Errors if `folder_path` is not a valid directory.
|
||||||
|
- Errors if `read_file_number` exceeds the number of files in the folder.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> using GeneralUtils
|
||||||
|
julia> result = read_textfile_by_index("/path/to/folder", 2)
|
||||||
|
(2, "sample.txt", ["line1", "line2", ...])
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
function read_textfile_by_index(folder_path::String, read_file_number::Integer=1)
|
function read_textfile_by_index(folder_path::String, read_file_number::Integer=1)
|
||||||
if isdir(folder_path)
|
if isdir(folder_path)
|
||||||
@@ -453,6 +473,34 @@ function randomChoiceOnTarget(target::AbstractVector, choiceList::AbstractVector
|
|||||||
return randomChoiceOnTarget.(target, 1, (choiceList,), (probability,))
|
return randomChoiceOnTarget.(target, 1, (choiceList,), (probability,))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
""" Compute the linearly weighted average of an array.
|
||||||
|
|
||||||
|
# What it does
|
||||||
|
- Assigns weights proportional to position indices (1, 2, 3, ...) to array
|
||||||
|
elements and returns the weighted average.
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
- `a::Array`
|
||||||
|
Array of numeric values. Elements must support multiplication with numbers
|
||||||
|
and summation.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- The linearly weighted average as a floating-point number.
|
||||||
|
|
||||||
|
# Formula
|
||||||
|
For an array `a` with `n` elements, computes:
|
||||||
|
```
|
||||||
|
sum(i * a[i]) / sum(a) for i = 1 to n
|
||||||
|
```
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> using GeneralUtils
|
||||||
|
julia> a = [10, 20, 30]
|
||||||
|
julia> linearly_weighted_avg(a)
|
||||||
|
23.333333333333332
|
||||||
|
```
|
||||||
|
"""
|
||||||
function linearly_weighted_avg(a::Array)
|
function linearly_weighted_avg(a::Array)
|
||||||
total = 0.0
|
total = 0.0
|
||||||
for (i, v) in enumerate(a)
|
for (i, v) in enumerate(a)
|
||||||
@@ -463,10 +511,36 @@ function linearly_weighted_avg(a::Array)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
""" Convert String that is holded inside a variable to Symbol
|
""" Convert a variable's value (String) into a Symbol.
|
||||||
# Example
|
|
||||||
x = "hello" # x is a variable holding String "hello" \n
|
# What it does
|
||||||
y = variable_to_symbol(x) # y holds :hello
|
- Takes a variable containing a String value and converts it to a Symbol
|
||||||
|
using Julia's expression interpolation mechanism.
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
- `variable`
|
||||||
|
Any variable whose value is a String. The function uses `string(variable)`
|
||||||
|
internally to obtain the value.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- A `Symbol` constructed from the string value of the input variable.
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
- This function uses `:$variable` interpolation to capture the variable's
|
||||||
|
value as a Symbol. It works with any variable type that can be converted
|
||||||
|
to String.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> using GeneralUtils
|
||||||
|
julia> x = "hello"
|
||||||
|
julia> variable_str_to_symbol(x)
|
||||||
|
:hello
|
||||||
|
|
||||||
|
julia> y = "world_test"
|
||||||
|
julia> variable_str_to_symbol(y)
|
||||||
|
:world_test
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
function variable_str_to_symbol(variable)
|
function variable_str_to_symbol(variable)
|
||||||
semi = :($variable)
|
semi = :($variable)
|
||||||
@@ -510,6 +584,45 @@ function fieldname_useable_type(somestruct, fieldname::Symbol;
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
""" Draw unique elements from a list without replacement.
|
||||||
|
|
||||||
|
# What it does
|
||||||
|
- Randomly selects a specified number of distinct elements from a collection,
|
||||||
|
optionally excluding certain elements from consideration. Uses in-place
|
||||||
|
shuffling for efficiency.
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
- `drawOptions::Array`
|
||||||
|
Collection of elements to draw from.
|
||||||
|
- `draw_number::Integer`
|
||||||
|
Number of unique elements to draw.
|
||||||
|
|
||||||
|
# Keyword Arguments
|
||||||
|
- `exclude_list::Union{AbstractArray,Nothing}=nothing`
|
||||||
|
Elements to exclude from the drawing pool. If `nothing`, no elements are
|
||||||
|
excluded.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- An array of `draw_number` unique elements drawn from `drawOptions`, excluding
|
||||||
|
any elements in `exclude_list`.
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
- The function copies `drawOptions` and shuffles in-place, then pops elements
|
||||||
|
sequentially to ensure uniqueness.
|
||||||
|
- Errors if `draw_number` exceeds the number of available elements after
|
||||||
|
exclusion.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> using GeneralUtils
|
||||||
|
julia> options = [1, 2, 3, 4, 5]
|
||||||
|
julia> randomNoRepeat(options, 3)
|
||||||
|
[3, 1, 5]
|
||||||
|
|
||||||
|
julia> randomNoRepeat(options, 2; exclude_list=[1, 5])
|
||||||
|
[4, 2]
|
||||||
|
```
|
||||||
|
"""
|
||||||
function randomNoRepeat(drawOptions::Array, draw_number::Integer;
|
function randomNoRepeat(drawOptions::Array, draw_number::Integer;
|
||||||
exclude_list::Union{AbstractArray,Nothing}=nothing)
|
exclude_list::Union{AbstractArray,Nothing}=nothing)
|
||||||
draw_option = copy(drawOptions)
|
draw_option = copy(drawOptions)
|
||||||
@@ -676,10 +789,36 @@ function selectRange(d::Dict{Symbol, <:AbstractVector}, range)
|
|||||||
return newDict
|
return newDict
|
||||||
end
|
end
|
||||||
|
|
||||||
""" Assign value to a given Dict by array of keys
|
""" assignDict!(dict::Dict, accessArray::Array{Symbol}, valueToAssign)
|
||||||
|
|
||||||
# Example
|
# What it does
|
||||||
d = Dict(
|
- Recursively traverses a nested dictionary structure using a vector of keys
|
||||||
|
and assigns a value to the final key. Creates intermediate dictionaries
|
||||||
|
if they don't exist.
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
- `dict::Dict`
|
||||||
|
The root dictionary to traverse and modify.
|
||||||
|
- `accessArray::Array{Symbol}`
|
||||||
|
A vector of symbols representing the key path to traverse.
|
||||||
|
- `valueToAssign`
|
||||||
|
The value to assign at the final key in the path.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- `0` on success (value assigned)
|
||||||
|
- `1` if the path cannot be traversed (missing intermediate keys)
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
- The function walks through each key in `accessArray` except the last one,
|
||||||
|
expecting intermediate keys to already exist in the dictionary.
|
||||||
|
- If any intermediate key is missing, the function returns `1` without
|
||||||
|
modifying the dictionary.
|
||||||
|
- The final key in `accessArray` receives the `valueToAssign`.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> using GeneralUtils
|
||||||
|
julia> d = Dict(
|
||||||
:a1=> Dict(:c=> 5),
|
:a1=> Dict(:c=> 5),
|
||||||
:a2=> Dict(
|
:a2=> Dict(
|
||||||
:k=> 10,
|
:k=> 10,
|
||||||
@@ -688,10 +827,11 @@ end
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
index = [:a2, :b, :s] \n
|
julia> assignDict!(d, [:a2, :b, :s], "wow")
|
||||||
assignDict!(d, [:a2, :b, :s], "wow")
|
0
|
||||||
|
julia> d[:a2][:b][:s]
|
||||||
return 1 if no target key in a given dict.
|
"wow"
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
function assignDict!(dict::Dict, accessArray::Array{Symbol}, valueToAssign)
|
function assignDict!(dict::Dict, accessArray::Array{Symbol}, valueToAssign)
|
||||||
wd = nothing
|
wd = nothing
|
||||||
@@ -712,9 +852,42 @@ function assignDict!(dict::Dict, accessArray::Array{Symbol}, valueToAssign)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
""" convert hour(0-23), minute(0-59) into julia time object
|
""" iTime(h::Integer, m::Integer)
|
||||||
# Example
|
|
||||||
time
|
# What it does
|
||||||
|
- Converts hour (0-23) and minute (0-59) into a Julia `Time` object using
|
||||||
|
12-hour format with AM/PM indicator.
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
- `h::Integer`
|
||||||
|
Hour in 24-hour format (0 to 23).
|
||||||
|
- `m::Integer`
|
||||||
|
Minute (0 to 59).
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- A `Time` object representing the time in 12-hour format with AM/PM.
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
- Hours 0 and 12 are special cases: 0 becomes 12 AM, 12 becomes 12 PM.
|
||||||
|
- Hours 1-11 remain the same with "am" suffix.
|
||||||
|
- Hours 13-23 are converted to 1-11 with "pm" suffix.
|
||||||
|
- Minutes less than 10 are zero-padded.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> using GeneralUtils
|
||||||
|
julia> iTime(0, 30)
|
||||||
|
12:30 AM
|
||||||
|
|
||||||
|
julia> iTime(9, 15)
|
||||||
|
9:15 AM
|
||||||
|
|
||||||
|
julia> iTime(12, 0)
|
||||||
|
12:00 PM
|
||||||
|
|
||||||
|
julia> iTime(14, 5)
|
||||||
|
2:05 PM
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
function iTime(h::Integer, m::Integer)
|
function iTime(h::Integer, m::Integer)
|
||||||
if h == 0
|
if h == 0
|
||||||
@@ -758,18 +931,39 @@ function limitvalue(v::Number, lowerbound::Pair, upperbound::Pair)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
""" Assign matrix b to matrix a according to matrix b's CartesianIndex.
|
""" cartesianAssign!(a, b)
|
||||||
|
|
||||||
Arguments:\n
|
# What it does
|
||||||
a : target matrix.
|
- Assigns elements from matrix `b` to matrix `a` using the Cartesian indices
|
||||||
b : source matrix.
|
of `b`. Elements are copied in the order they appear when iterating over `b`,
|
||||||
|
and placed into `a` at the corresponding Cartesian positions of `b`.
|
||||||
|
|
||||||
Return:\n
|
# Arguments
|
||||||
Resulting matrix a.
|
- `a`
|
||||||
|
Target matrix where values from `b` will be assigned.
|
||||||
|
- `b`
|
||||||
|
Source matrix whose Cartesian indices determine where values are placed in `a`.
|
||||||
|
|
||||||
Example:\n
|
# Return
|
||||||
|
- `nothing`
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
- The function iterates through `b` in column-major order (Julia's default),
|
||||||
|
retrieving each element's Cartesian index and assigning it to the same
|
||||||
|
position in `a`.
|
||||||
|
- Matrix `a` must have sufficient size to accommodate all Cartesian indices
|
||||||
|
from `b`; otherwise, an `BoundsError` may occur.
|
||||||
|
|
||||||
|
# Examples
|
||||||
```jldoctest
|
```jldoctest
|
||||||
julia> not done yet
|
julia> using GeneralUtils
|
||||||
|
julia> a = zeros(4, 4);
|
||||||
|
julia> b = [1 2; 3 4];
|
||||||
|
julia> cartesianAssign!(a, b);
|
||||||
|
julia> a[1:2, 1:2]
|
||||||
|
2×2 Matrix{Float64}:
|
||||||
|
1.0 3.0
|
||||||
|
2.0 4.0
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function cartesianAssign!(a, b)
|
function cartesianAssign!(a, b)
|
||||||
@@ -1125,7 +1319,6 @@ julia> text = "{\"ask\": {\"text\": \"Could you please tell me about the special
|
|||||||
julia> GeneralUtils.getStringBetweenCharacters(text, '{', '}', endCharLocation="end")
|
julia> GeneralUtils.getStringBetweenCharacters(text, '{', '}', endCharLocation="end")
|
||||||
"{\"ask\": {\"text\": \"Could you please tell me about the special event?\"\n}}"
|
"{\"ask\": {\"text\": \"Could you please tell me about the special event?\"\n}}"
|
||||||
```
|
```
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
function getStringBetweenCharacters(text::T, startChar::Char, endChar::Char;
|
function getStringBetweenCharacters(text::T, startChar::Char, endChar::Char;
|
||||||
endCharLocation::String="next", includeChar::Bool=true)::String where {T<:AbstractString}
|
endCharLocation::String="next", includeChar::Bool=true)::String where {T<:AbstractString}
|
||||||
@@ -1157,59 +1350,43 @@ function getStringBetweenCharacters(text::T, startChar::Char, endChar::Char;
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
""" mkDictPath!(dict::Union{Dict{Symbol, Any}, Dict{String, Any}}, addkeys::Union{Vector{String}, Vector{Symbol}}, value)
|
||||||
|
|
||||||
""" Read JSON string and return a dictionary with string key. (JSON3 defaults to symbol key)
|
# What it does
|
||||||
This function solve the problem of reading JSON with string key.
|
- Recursively creates nested dictionary paths if they do not exist and assigns
|
||||||
|
a value to the final key. Similar to `mkpath()` but for dictionaries.
|
||||||
Arguments:
|
|
||||||
jsonString::String
|
|
||||||
|
|
||||||
Return:
|
|
||||||
a dictionary with string key
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```jldoctest
|
|
||||||
julia> jsonString = {\"wine type\": \"Red\", \"intensity level\": \"medium-bodied\"}
|
|
||||||
julia> JSON3read_stringKey(jsonString)
|
|
||||||
Dict{String, Any} with 2 entries:
|
|
||||||
"intensity level" => "medium-bodied"
|
|
||||||
"wine type" => "Red"
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
function JSON3read_stringKey(jsonString::AbstractString)
|
|
||||||
jsonobj = JSON3.read(jsonString)
|
|
||||||
newDict = OrderedDict{String,Any}()
|
|
||||||
for (k,v) in jsonobj
|
|
||||||
newDict[string(k)] = v
|
|
||||||
end
|
|
||||||
return newDict
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
""" Create nested dict path if it does not already exist. The same concept as Julia's mkpath()
|
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `dict::Dict`
|
- `dict::Union{Dict{Symbol, Any}, Dict{String, Any}}`
|
||||||
target dict
|
The target dictionary to traverse and modify. Must use consistent key types
|
||||||
|
(either all `String` or all `Symbol`).
|
||||||
- `addkeys::Union{Vector{String}, Vector{Symbol}}`
|
- `addkeys::Union{Vector{String}, Vector{Symbol}}`
|
||||||
keys to be added to dict
|
A vector of keys representing the path to traverse. Intermediate dictionaries
|
||||||
|
are created if they don't exist.
|
||||||
- `value`
|
- `value`
|
||||||
value to be added to dict at final key in keypath
|
The value to assign at the final key in the path.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- dict with added keypath
|
- The assigned `value`.
|
||||||
|
|
||||||
# Example
|
# Notes
|
||||||
|
- The function ensures key type consistency: the type of keys being added must
|
||||||
|
match the type of existing keys in the dictionary.
|
||||||
|
- Intermediate dictionaries are automatically created with the appropriate key
|
||||||
|
type when they don't exist.
|
||||||
|
- The function walks through each key in `addkeys` except the last one,
|
||||||
|
creating intermediate dictionaries as needed, and assigns `value` to the final
|
||||||
|
key.
|
||||||
|
|
||||||
|
# Examples
|
||||||
```jldoctest
|
```jldoctest
|
||||||
julia> using Revise
|
|
||||||
julia> using GeneralUtils
|
julia> using GeneralUtils
|
||||||
julia> d = Dict{String, Any}("a" => Dict{String, Any}("b" => 10))
|
julia> d = Dict("a" => Dict("b" => 10))
|
||||||
julia> GeneralUtils.mkDictPath!(d, ["a", "v", "x", "y", "z"], 42)
|
julia> mkDictPath!(d, ["a", "v", "x", "y", "z"], 42)
|
||||||
Dict{String, Any} with 1 entry:
|
42
|
||||||
"path" => Dict{Any, Any}("to"=>Dict{Any, Any}("nested"=>Dict{Any, Any}("value"=>42)))
|
julia> d["a"]["v"]["x"]["y"]["z"]
|
||||||
|
42
|
||||||
```
|
```
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
function mkDictPath!(dict::Union{Dict{Symbol, Any}, Dict{String, Any}},
|
function mkDictPath!(dict::Union{Dict{Symbol, Any}, Dict{String, Any}},
|
||||||
addkeys::Union{Vector{String}, Vector{Symbol}}, value)
|
addkeys::Union{Vector{String}, Vector{Symbol}}, value)
|
||||||
@@ -1233,27 +1410,36 @@ function mkDictPath!(dict::Union{Dict{Symbol, Any}, Dict{String, Any}},
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
""" Get nested dict value using a vector of keys
|
""" getDictPath(dict::Dict, keys::Vector)
|
||||||
|
|
||||||
|
# What it does
|
||||||
|
- Retrieves a value from a nested dictionary by traversing a vector of keys.
|
||||||
|
Creates intermediate dictionaries if they don't exist.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `dict::Dict`
|
- `dict::Dict`
|
||||||
target dict
|
The root dictionary to traverse.
|
||||||
- `keys::Vector`
|
- `keys::Vector`
|
||||||
keys vector
|
A vector of keys representing the path to traverse. Each key in the vector
|
||||||
|
is used to access the next level of nesting.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- dict with added keypath
|
- The value at the final key in the path.
|
||||||
|
|
||||||
# Example
|
# Notes
|
||||||
|
- Errors with `ArgumentError` if any intermediate key is missing from the
|
||||||
|
dictionary path.
|
||||||
|
- The function walks through each key in `keys` except the last one,
|
||||||
|
expecting intermediate keys to exist in the dictionary.
|
||||||
|
- The final key in `keys` is used to retrieve the value.
|
||||||
|
|
||||||
|
# Examples
|
||||||
```jldoctest
|
```jldoctest
|
||||||
julia> using Revise
|
|
||||||
julia> using GeneralUtils
|
julia> using GeneralUtils
|
||||||
julia> d = Dict{Symbol, Any}(:a => Dict{Symbol, Any}(:b => 10))
|
julia> d = Dict(:a => Dict(:b => 10))
|
||||||
julia> GeneralUtils.getDictPath(d, [:a, :b])
|
julia> getDictPath(d, [:a, :b])
|
||||||
10
|
10
|
||||||
```
|
```
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
function getDictPath(dict::Dict, keys::Vector)
|
function getDictPath(dict::Dict, keys::Vector)
|
||||||
current_dict = dict
|
current_dict = dict
|
||||||
@@ -1405,8 +1591,6 @@ OrderedCollections.OrderedDict{Any, Any}(:thought => "what to do",
|
|||||||
:plan => "wake up and going out",
|
:plan => "wake up and going out",
|
||||||
:action => "1. wake up 2. eat 3. sleep")
|
:action => "1. wake up 2. eat 3. sleep")
|
||||||
```
|
```
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
function textToDict(text::String, detectKeywords::Vector{String};
|
function textToDict(text::String, detectKeywords::Vector{String};
|
||||||
dictKey::Union{Vector{String}, Nothing}=nothing,
|
dictKey::Union{Vector{String}, Nothing}=nothing,
|
||||||
@@ -1467,6 +1651,80 @@ function textToDict(text::String, detectKeywords::Vector{String};
|
|||||||
return od2
|
return od2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
""" Recursively convert dictionary into an HTML string representation.
|
||||||
|
|
||||||
|
# What it does
|
||||||
|
- Walks a nested `AbstractDict` structure and produces a well-formed HTML string
|
||||||
|
where each dictionary key becomes an HTML tag. Nested dictionaries become
|
||||||
|
nested tags, and scalar values (numbers, strings, etc.) become the text
|
||||||
|
content of leaf tags.
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
- `d::AbstractDict`
|
||||||
|
The dictionary to convert. Keys must be strings or symbols that form valid
|
||||||
|
HTML tag names.
|
||||||
|
|
||||||
|
# Keyword Arguments
|
||||||
|
- `indent_level::Integer=1`
|
||||||
|
Initial indentation level for the output. Each recursive level increases
|
||||||
|
indentation by one.
|
||||||
|
- `indent_str::String=" "`
|
||||||
|
String used for each indentation level.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- A single HTML string representing the dictionary structure, with proper
|
||||||
|
opening and closing tags and appropriate indentation.
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
- Keys are sorted alphabetically for deterministic output.
|
||||||
|
- Works recursively: dictionary values produce nested tags; non-dictionary
|
||||||
|
values are placed as text between opening/closing tags.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> d = Dict(
|
||||||
|
"html" => Dict(
|
||||||
|
"head" => Dict("title" => "Test"),
|
||||||
|
"body" => Dict(
|
||||||
|
"h1" => "Hello",
|
||||||
|
"p" => "World"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
julia> println(dict_to_string_html(d))
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello</h1>
|
||||||
|
<p>World</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
function dict_to_string_html(d::AbstractDict; indent_level=1, indent_str=" ")
|
||||||
|
lines = String[]
|
||||||
|
padding = indent_str ^ indent_level
|
||||||
|
|
||||||
|
# Sort keys for predictable, clean output
|
||||||
|
for k in sort(collect(keys(d)))
|
||||||
|
v = d[k]
|
||||||
|
|
||||||
|
if v isa AbstractDict
|
||||||
|
# Open tag, recurse for children, then close tag
|
||||||
|
push!(lines, "$padding<$k>")
|
||||||
|
ind_level = indent_level + 1
|
||||||
|
push!(lines, dict_to_string_html(v; indent_level=ind_level, indent_str=indent_str))
|
||||||
|
push!(lines, "$padding</$k>")
|
||||||
|
else
|
||||||
|
# Leaf node: put key and value on a single line
|
||||||
|
push!(lines, "$padding<$k>$v</$k>")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return join(lines, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user