如何使用 Javascript 从值数组中获取深度嵌套的对象结构
How to get deeply nested object structure from array of values with Javascript
我有 JSON 在文本编辑器中表示一些内容。这是一个示例:
{ "type": "doc", "content": [ { "type": "paragraph", "content": [ { "type": "text", "marks": [ { "type": "bold" } ], "text": "Testing" }, { "type": "text", "text": " " }, { "type": "text", "marks": [ { "type": "strike" } ], "text": "Testing " }, { "type": "text", "marks": [ { "type": "strike" }, { "type": "underline" } ], "text": "Testing" }, { "type": "text", "marks": [ { "type": "strike" } ], "text": " Testing" } ] }, { "type": "paragraph" }, { "type": "paragraph", "content": [ { "type": "text", "marks": [ { "type": "bold" } ], "text": "Testing " }, { "type": "text", "marks": [ { "type": "bold" }, { "type": "italic" }, { "type": "strike" } ], "text": "Testing" }, { "type": "text", "marks": [ { "type": "bold" } ], "text": " Testing" } ] }, { "type": "paragraph" } ] }
很好,因为我可以安全地将它转换为 html,但是它没有嵌套样式值,而是在 marks
子数组中表示此样式。
如果存储已经相对于其自然层次嵌套的数据,我更喜欢什么。
所以代替:
{
"type":"text",
"marks": [{ "type": "bold" }, { "type": "italic" }],
"text": "Testing"
}
我想要一些更准确地代表结果的东西 HTML:
{
"type" : "bold",
"content" : [{
"type" : "italic",
"content":[{
"type" : "text",
"text" : "Testing"
}]
}]
}
我已经尝试了多种解析 json 并像下面这样存储它的方法,但我认为我缺少一些关于 javascript 如何处理对象的基本知识,因为更改是'尚未制作。
我对下面的函数进行了各种迭代,遍历 json 中的每个 marks
数组。
item = {type:type, text:text}
marks.forEach((mark)=>{
let newObj = {content:[], type:mark.type}
item = newObj.content.push(item)
});
一些额外的背景信息,这是json由基于prosemirror的tiptap wysiwyg编辑器生成的。我无法使用正常的 html 导出,因为我正在对数据进行特殊处理。任何帮助将不胜感激。
编辑:Dacre Denny 使用 reduceRight()
提出了一个答案,它回答了问题的第一部分。但是,下面的函数仍然returns原来的对象不变。
const content = editorContent.content
function parseContent (arr) {
arr.forEach((item)=>{
// Check if item contains another array of items, and then iterate
over that one too.
if(item.content){
parseContent(item.content)
}
if(item.marks){
//Extract values from item
// THis is the correct function
const processContent = ({ marks, text }) =>
marks.reduceRight((acc, mark) => ({ type: mark.type, content: [acc]
}), {
type: "text",
text: text
});
item = processContent({ text:item.text, marks:item.marks })
}
})
}
parseContent(content)
return content
//
一种可能性是使用 reduceRight
到 "reduce" 输入内容的 marks
子数组到具有所需 "nested structure" 的单个对象。
想法是从 { type : "text", text : content.text }
对象(将嵌套)开始减少,然后递增 "wrap" 该对象与包含 "type" 数据的对象。
要使具有类型元数据的对象实现 "wrapping" 的正确顺序,需要反向减少 marks
数组。这就是为什么使用 reduceRight
(而不是常规 reduce
)的原因。
这里有一个示例片段来展示这个想法的实际效果:
/* Helper function processes the content object, returns the required
nested structure */
const processContent = ({ marks, text }) =>
marks.reduceRight((acc, mark) => ({ type: mark.type, content: [acc]
}), {
type: "text",
text: text
});
console.log(processContent({
"type": "text",
"marks": [{
"type": "bold"
}, {
"type": "italic"
}],
"text": "Testing"
}))
/*
Result:
{
"type" : "bold",
"content" : [{
"type" : "italic",
"content":[{
"type" : "text",
"text" : "Testing"
}]
}]
}
*/
希望对您有所帮助!
我有 JSON 在文本编辑器中表示一些内容。这是一个示例:
{ "type": "doc", "content": [ { "type": "paragraph", "content": [ { "type": "text", "marks": [ { "type": "bold" } ], "text": "Testing" }, { "type": "text", "text": " " }, { "type": "text", "marks": [ { "type": "strike" } ], "text": "Testing " }, { "type": "text", "marks": [ { "type": "strike" }, { "type": "underline" } ], "text": "Testing" }, { "type": "text", "marks": [ { "type": "strike" } ], "text": " Testing" } ] }, { "type": "paragraph" }, { "type": "paragraph", "content": [ { "type": "text", "marks": [ { "type": "bold" } ], "text": "Testing " }, { "type": "text", "marks": [ { "type": "bold" }, { "type": "italic" }, { "type": "strike" } ], "text": "Testing" }, { "type": "text", "marks": [ { "type": "bold" } ], "text": " Testing" } ] }, { "type": "paragraph" } ] }
很好,因为我可以安全地将它转换为 html,但是它没有嵌套样式值,而是在 marks
子数组中表示此样式。
如果存储已经相对于其自然层次嵌套的数据,我更喜欢什么。
所以代替:
{
"type":"text",
"marks": [{ "type": "bold" }, { "type": "italic" }],
"text": "Testing"
}
我想要一些更准确地代表结果的东西 HTML:
{
"type" : "bold",
"content" : [{
"type" : "italic",
"content":[{
"type" : "text",
"text" : "Testing"
}]
}]
}
我已经尝试了多种解析 json 并像下面这样存储它的方法,但我认为我缺少一些关于 javascript 如何处理对象的基本知识,因为更改是'尚未制作。
我对下面的函数进行了各种迭代,遍历 json 中的每个 marks
数组。
item = {type:type, text:text}
marks.forEach((mark)=>{
let newObj = {content:[], type:mark.type}
item = newObj.content.push(item)
});
一些额外的背景信息,这是json由基于prosemirror的tiptap wysiwyg编辑器生成的。我无法使用正常的 html 导出,因为我正在对数据进行特殊处理。任何帮助将不胜感激。
编辑:Dacre Denny 使用 reduceRight()
提出了一个答案,它回答了问题的第一部分。但是,下面的函数仍然returns原来的对象不变。
const content = editorContent.content
function parseContent (arr) {
arr.forEach((item)=>{
// Check if item contains another array of items, and then iterate
over that one too.
if(item.content){
parseContent(item.content)
}
if(item.marks){
//Extract values from item
// THis is the correct function
const processContent = ({ marks, text }) =>
marks.reduceRight((acc, mark) => ({ type: mark.type, content: [acc]
}), {
type: "text",
text: text
});
item = processContent({ text:item.text, marks:item.marks })
}
})
}
parseContent(content)
return content
//
一种可能性是使用 reduceRight
到 "reduce" 输入内容的 marks
子数组到具有所需 "nested structure" 的单个对象。
想法是从 { type : "text", text : content.text }
对象(将嵌套)开始减少,然后递增 "wrap" 该对象与包含 "type" 数据的对象。
要使具有类型元数据的对象实现 "wrapping" 的正确顺序,需要反向减少 marks
数组。这就是为什么使用 reduceRight
(而不是常规 reduce
)的原因。
这里有一个示例片段来展示这个想法的实际效果:
/* Helper function processes the content object, returns the required
nested structure */
const processContent = ({ marks, text }) =>
marks.reduceRight((acc, mark) => ({ type: mark.type, content: [acc]
}), {
type: "text",
text: text
});
console.log(processContent({
"type": "text",
"marks": [{
"type": "bold"
}, {
"type": "italic"
}],
"text": "Testing"
}))
/*
Result:
{
"type" : "bold",
"content" : [{
"type" : "italic",
"content":[{
"type" : "text",
"text" : "Testing"
}]
}]
}
*/
希望对您有所帮助!