我很惊讶在StackOverflow上没有人问过这个问题。
查看JSON对象文档和快速谷歌搜索都没有得到令人满意的结果。
它有什么优势?它是如何工作的?
编辑:为了更清晰,看一下这个展开/折叠的例子。
谢谢。
我很惊讶在StackOverflow上没有人问过这个问题。
查看JSON对象文档和快速谷歌搜索都没有得到令人满意的结果。
它有什么优势?它是如何工作的?
编辑:为了更清晰,看一下这个展开/折叠的例子。
谢谢。
有很多情况下,你会得到一些由某个库自动构建的JSON文本。在编程语言中,有很多库可以构建JSON文本(一个例子在这里)。
每当库添加一些额外的对象或数组包装时,您可能希望摆脱它们,因为您将JSON发送到服务器并且您在那里的代码崩溃,因为它期望原始值而不是对象(或数组)。或者,如果您的JSON是服务器响应,则不希望生成的Javascript代码必须区分对象/数组或非对象/数组。在所有这些情况下,展平都是有用的,因为它将节省您的时间。您将必须实现较少的if / else,并且可以可靠地期望数据结构尽可能平坦。
改进上述场景的另一种方法是以最大健壮的方式编写代码,以便它永远不会因多余的包装而崩溃。因此,始终预期一些包装并获取其内容。然后,展平就不需要了。
你看,这取决于构建JSON的内容以及解析它的内容。构建可能超出您的范围。
这也引出了数据模型问题。如果某些 XY 没有 0 条记录或有 >0 条记录,则我曾经使用需要不同解析方式的 XML 代码进行工作。拥有一个允许具有 0 或多个 XY 条目的包装器将使生活更加轻松。这些是数据模型决策。JSON.stringify()
、json_encode()
等)。POST
update=1
&user.id=12345
&user.email=testmail@domain.tld
&user.profile.name=Mr. Test
&user.profile.age=42
&user.profile.friend.0.email=tom@domain.tld
&user.profile.friend.1.email=sally@domain.tld
&user.profile.friend.2.email=bob@domain.tld
&user.profile.skill.0.id=100
&user.profile.skill.0.name=javascript
&user.profile.skill.1.id=200
&user.profile.skill.1.name=piano
所有内容都已经在一个平面结构中,为什么不采用简单的一对一绑定呢?如果您有一系列需要执行的约束或安全要求,您可以通过直接在排序键列表上搜索来验证它们。
平面结构更易于人们理解和处理,甚至与数据库去规范化存在一些交叉。它还允许以可读性更强但更冗长的方式实现特定上下文的安全性和约束。
当完整显示用户视图时,您可能希望隐藏用户技能列表中主键ID的显示。
"user.profile.skill.#.id": { hidden: true, readonly: true }
但是,当直接查看技能(作为管理员可能需要编辑技能)时,您可能想要查看ID。
"skill.id": { readonly: true }
Hello {{firstName}},
It is amazing you chose to join our site. We are happy to have you on board.
To get started, we would really love it if you can confirm your email address
by clicking on the link: {{confirm_url}}.
Welcome aboard
The Team!
假设我们有以下 JSON 对象在内存中:
{
"user" : {
"prefix" : "Dr.",
"firstName" : "Awah",
"lastName" : "Teh",
"email" : "awah@superduperubercoolsite.com",
"address" : {
"street": "100 Main St",
"city" : "PleasantVille",
"state" : "NY",
"phone" : "+1-212-555-1212"
}
},
"meta" : {
"confirm_url" : "http://superduperubercoolsite.com/confirm/ABC123"
}
}
使用正则表达式替换似乎非常简单,如下所示(假设我们的电子邮件模板字符串存储在名为template
的变量中,json对象存储在名为templateData
的变量中):
template = template.replace(new RegExp('{{firstName}}', 'g'), templateData.user.firstName);
template = template.replace(new RegExp('{{confirm_url}}', 'g'), templateData.meta.confirm_url);
简单易懂,对吧? --> 实际上是的!但如果这个邮件有10个模板字段呢?或者你想将模板与代码解耦,将其存储在像SendGrid这样的单独系统中,让你酷炫的市场负责人可以访问模板并更改复制语言,而无需打电话给工程师进行代码更改、测试和重新部署(多么麻烦)。
现在有许多展开JSON的方法,我在这个codepen链接中编写了一个逻辑来展开JSON(实际上,我在方法flattenJSONIntoKVP
和flattenJSONIntoRAW
中演示了两种相似但不同的方法,请查看它们!)。
话虽如此,还有其他的实现方式,值得记住的是,本篇文章的重点是讨论为什么JSON展开可能有用,而不是如何展开。
接下来!假设您使用我的实现方式将上面的JSON(结果为键值对)展开成以下内容:
[
{ "key": "user.prefix", "value": "Dr."},
{ "key": "user.firstName", "value": "Awah"},
{ "key": "user.lastName", "value": "Teh"},
{ "key": "user.email", "value": "awah@superduperubercoolsite.com"},
{ "key": "user.address.street", "value": "100 Main St"},
{ "key": "user.address.city", "value": "{PleasantVille"},
{ "key": "user.address.state", "value": "NY"},
{ "key": "user.address.phone", "value": "+1-212-555-1212"},
{ "key": "meta.confirm_url", "value": "http://superduperubercoolsite.com/confirm/ABC123"},
]
为什么呢?因为现在你可以动态地使用来自JSON对象的值对模板字符串进行插值
而不必过度关注JSON的结构(如果由于应用程序演变而导致JSON发生更改,您不必也记得来到这里更改此插值代码-您只需要更新电子邮件模板本身,这是在SendGrid上[根据此示例])。
那么要如何做呢?简单,迭代。让我们假设从上面扁平化的内容存储在一个名为flatJSON
的变量中:
///Notice how I use Javascripts native string interpolation to create my RegExp
///Also note that I am replacing the dot (.) in my flattened JSON variable names with a double underscore (__), I only do this because my intended target is SendGrid, and I don't believe it likes dots in its template placeholders.
flatJSON.forEach(kvp=>template = template.replace(new RegExp(`{{${kvp.key.replace(/\./g, '__'}}}`, 'g'), kvp.value));
仅仅一行代码就可以替代可能需要十甚至数百甚至上千行代码(好吧..也许不是上千行,但你明白我的意思)。
请注意,现在,在我们的新模板字符串中,我们可以使用类似完全限定域名的样式变量来映射回我们的原始JSON(理想情况下,如果SendGrid支持在其模板占位符中使用点号,这看起来会非常棒,但有时候不能赢得所有!)。
Hello {{user__firstName}},
It is amazing you chose to join our site. We are happy to have you on board.
To get started, we would really love it if you can confirm your email address
by clicking on the link: {{meta__confirm_url}}.
Welcome aboard {{user__prefix}} {{user__lastName}}!
The Team!
就这样,我们今天完成了一些好事:
eval
方法(我们可以在另一篇文章中讨论大而丑陋的eval)。