gpt4 book ai didi

json - 在 TCL 中的字典中创建字典列表

转载 作者:行者123 更新时间:2023-12-04 10:23:47 26 4
gpt4 key购买 nike

我被迫使用 TCL 做一些事情,我需要创建一个像这样的 json 字符串:

{ "mainKey": "mainValue", "subKey": [{"key1":"value1"},{"key2":"value2"}]}

所以我正在尝试这样做:

set subDict1 [dict create key1 value1]
set subDict2 [dict create key2 value2]
set subDictList [list $subDict1 $subDict2]
set finalDict [dict create mainKey mainValue subKey $subDictList]

当我将这个 dict 转换为 json 时,我得到:

{"mainKey":"mainValue", "subKey":{"key1 value1":{"key2":"value2"}}} 

而不是要求的:

{ "mainKey": "mainValue", "subKey": [{"key1":"value1"},{"key2":"value2"}]}

我做错了什么?

最佳答案

首先你要明白TCL是一种非常无类型的语言。 tcl 中的列表和字典到底是什么?

在 Tcl 中,列表是一个格式正确的字符串,其中列表的每个成员都由空格(空格、制表符或换行符)分隔,如果项目包含的数据包含空格,则可以通过以下方式对它们进行转义:

  1. 使用反斜杠转义:

    "this is a list\ of\ four\ items"
  2. 使用""分组:

    {this is a "list of four items"}
  3. 使用 {} 分组:

    {this is a {list of four items}}

请注意,在内部,一旦字符串被解析为列表,Tcl 会使用不同的内部数据结构来存储列表以提高速度。但在语义上它仍然是一个字符串。就像 HTML 是一种特殊格式的字符串或 JSON 是一种特殊格式的字符串一样,Tcl 的态度是列表不过是特殊格式的字符串。

那么,什么是字典?在 Tcl 中,字典是包含偶数个元素的列表。就是这样。没什么特别的。因此,字典在语义上也是一个字符串(尽管如上所述,一旦 tcl 发现您将该字符串用作字典,它就会将其编译为不同的数据结构以优化速度)。

再次注意 tcl 的核心理念:几乎所有数据结构(数组除外)都只是字符串,它们恰好以具有特殊含义的方式格式化。

这就是您无法将 tcl 数据结构自动转换为 JSON 的原因 - 如果您要求 Tcl 猜测数据结构是什么,您最终会得到编写猜测函数的程序员想要的任何数据结构。在您的情况下,它看起来默认总是检测包含偶数个元素的列表作为字典。

那么如何才能正确生成JSON呢?

有几种方法可以做到这一点。您当然可以使用自定义专用 for 循环或函数将您的数据结构(同样,它只是一个特殊格式的字符串)转换为 JSON。

几年前我编写了这个 JSON 编译器:

# data is plain old tcl values
# spec is defined as follows:
# {string} - data is simply a string, "quote" it if it's not a number
# {list} - data is a tcl list of strings, convert to JSON arrays
# {list list} - data is a tcl list of lists
# {list dict} - data is a tcl list of dicts
# {dict} - data is a tcl dict of strings
# {dict xx list} - data is a tcl dict where the value of key xx is a tcl list
# {dict * list} - data is a tcl dict of lists
# etc..
proc compile_json {spec data} {
while [llength $spec] {
set type [lindex $spec 0]
set spec [lrange $spec 1 end]

switch -- $type {
dict {
lappend spec * string

set json {}
foreach {key val} $data {
foreach {keymatch valtype} $spec {
if {[string match $keymatch $key]} {
lappend json [subst {"$key":[
compile_json $valtype $val]}]
break
}
}
}
return "{[join $json ,]}"
}
list {
if {![llength $spec]} {
set spec string
} else {
set spec [lindex $spec 0]
}
set json {}
foreach {val} $data {
lappend json [compile_json $spec $val]
}
return "\[[join $json ,]\]"
}
string {
if {[string is double -strict $data]} {
return $data
} else {
return "\"$data\""
}
}
default {error "Invalid type"}
}
}
}

(有关 JSON 解析的原始实现和讨论,请参阅 http://wiki.tcl.tk/JSON)

因为 tcl 永远无法正确猜测您的“字符串”是什么,所以我选择为函数提供格式字符串,以便正确解释 tcl 数据结构。例如,使用上面的函数来编译你的字典,你可以这样调用它:

compile_json {dict subKey list} finalDict

我恳求 tcllib 维护者窃取我的代码,因为我仍然相信这是在 tcl 中处理 JSON 的正确方法,但到目前为止它仍然不在 tcllib 中。

顺便说一句:我将上面的代码许可为公共(public)领域,如果您愿意,您或任何人都可以声明它的全部作者身份。

关于json - 在 TCL 中的字典中创建字典列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25814950/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com