【问题标题】:How to get deeply nested object structure from array of values with Javascript如何使用 Javascript 从值数组中获取深度嵌套的对象结构
【发布时间】:2019-10-06 20:59:35
【问题描述】:

我有 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)
});

一些额外的背景信息,这是tiptap所见即所得编辑器生成的json,它是基于prosemirror的。我无法使用正常的 html 导出,因为我正在对数据进行特殊处理。任何帮助将不胜感激。

编辑:Dacre Denny 使用reduceRight() 提出了一个答案,它回答了问题的第一部分。但是,下面的函数仍然返回原始对象不变。

   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
//

【问题讨论】:

    标签: javascript json prose-mirror


    【解决方案1】:

    一种可能是使用reduceRight 将输入内容的marks 子数组“减少”为具有所需“嵌套结构”的单个对象。

    这个想法是从{ type : "text", text : content.text } 对象(将被嵌套)开始减少,然后用包含“类型”数据的对象逐步“包装”该对象。

    要为元数据类型的对象实现正确的“包装”顺序,marks 数组需要反向减少。这就是使用reduceRight 的原因(而不是常规的reduce)。

    这里有一个例子 sn-p 来展示这个想法:

    /* 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"
           }]
       }]
    }
    */

    希望有帮助!

    【讨论】:

    • 非常感谢,这绝对是正确的做法!但是,我仍然无法评估新价值。 item = processContent 只是给我留下了与我开始时相同的对象。
    • 不客气 - 看起来您将 processContent 函数分配给了 item。如果您将代码更改为var item = processContent({ text:text, marks : marks }),是否会按预期工作?
    • 当我将它记录到控制台时效果很好,但之后对象仍然相同。我在遍历整个对象的 forEach 循环中完成所有这些工作。所以我在循环中分配值。更改类型的字符串属性很好,但是当我尝试为对象分配新值时它不起作用。
    • 您能否通过在此处添加一些您描述的周围代码来更新上面的问题?这应该会给我更多的背景信息,以便我可以更好地提供帮助:)
    • 当然,再次感谢,我已经更新了问题,包括我用来更新对象(或不更新)的函数
    猜你喜欢
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多