Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从多个嵌套数组创建新的数据对象集_Javascript_Arrays_Typescript_Multidimensional Array - Fatal编程技术网

Javascript 从多个嵌套数组创建新的数据对象集

Javascript 从多个嵌套数组创建新的数据对象集,javascript,arrays,typescript,multidimensional-array,Javascript,Arrays,Typescript,Multidimensional Array,我有一个复杂的数据结构,有多个嵌套数组 以下是目前的结构 var contentData = { data: { content: [ { type: "column", sections: [ { sub: [ { type: "heading-1", text: "Heading Text"

我有一个复杂的数据结构,有多个嵌套数组

以下是目前的结构

var contentData = {
  data: {
    content: [
      {
        type: "column",
        sections: [
          {
            sub: [
              {
                type: "heading-1",
                text: "Heading Text"
              }
            ]
          }
        ]
      },
      {
        type: "acc-item",
        sections: [
          {
            sub: [
              {
                type: "heading-1",
                text: "Heading Text"
              },
              {
                type: "ordered-item",
                text: "Item 1"
              },
              {
                type: "unordered-item",
                text: "Item 2"
              }
            ]
          }
        ]
      },
      {
        type: "acc-item",
        sections: [
          {
            sub: [
              {
                type: "heading-1",
                text: "Heading Text 2"
              }
            ]
          }
        ]
      }
    ]
  }
}
所以我想要的是

  • 我想将所有
    有序项和无序项
    分组到一个新对象中,如
    {type:'list',items:[所有列表项]}

  • 我需要提取
    sub
    中的所有项目,并将其推送到新对象
    embedded
    ,它应该放置在根级别,如下所示

    {type:“acc项目”,嵌入:[{type:“heading-1”,text:“heading-text 2”}]}

  • 到目前为止我所做的

    我可以分组
    acc项目
    ,但不能分组
    已订购项目和未订购项目

    所以我的最终预期结果应该是这样的

    [{
      "type": "column",
      "embedded": [
        {
          "type": "heading-1",
          "text": "Heading Text"
        }
      ]
    },
    {
      "type": "acc-group",
      "items": [
        {
          "type": "acc-item",
          "embedded": [
            {
              "type": "heading-1",
              "text": "Heading Text"
            },
            {
              "type": "list",
              "items": [
                {
                  "type": "ordered-item",
                  "text": "Item 1"
                },
                {
                  "type": "unordered-item",
                  "text": "Item 2" 
                }
              ]
            }
          ]
        },
        {
          "type": "acc-item",
          "embedded": [
            {
              "type": "heading-1",
              "text": "Heading Text 2"
            }
          ]
        }
      ]
    }]
    
    下面是我的代码

    var组,contentData={data:{content:[{type:“column”,sections:[{sub:[{type:“heading-1”,text:“heading-text”}]}},{type:“acc-item”,sections:[{sub:[{type:“heading-1”,text:“heading-text”},{type:“item 1”},{type:“无序项”,text:“item:“item 2”}},{type:“acc-item:{sub type:[{type:“heading-1”,“heading-text:”heading-text:}},类型=[“列表”、[“已订购项目”、“未订购项目”]、[“手风琴”、[“acc项目”]];
    var result=contentData.data.content.reduce((r,o)=>{
    var type=(types.find({1:values})=>values.indexOf(o.type)>-1)|{}[0];
    如果(!类型){
    r、 推(o);
    组=未定义;
    返回r;
    }
    如果(!group | | group.type!==type){
    组={type,items:[]};
    r、 推(组);
    }
    分组项目推送(o);
    返回r;
    }, []);
    document.body.innerHTML=''+JSON.stringify(结果,null'')+''和方法非常适合这种情况

        const groupedData = contentData.data.content.reduce((acc, cur) => {
            //Check if this indexed array already exists, if not create it. 
            const currentArray = (acc[`${cur.type}-group`] && acc[`${cur.type}-group`].items) || [];
    
            return {
              ...acc,
              [`${cur.type}-group`]: {
                  type: `${cur.type}-group`, 
                  items: [...currentArray, cur]
              }
            }
        }, {}); 
    
    你是对的,这是一种复杂的逻辑

    我建议您确实需要为此进行一些单元测试,并尝试将其分解成不同的部分

    我想我会这么做的

    1。按类型分组以创建分组。

    实际上,我正在创建一个您在这里要求的更通用的解决方案。也就是说,我不仅仅是对“acc项目”进行分组,而是对所有项目进行分组

    我快速搜索了“array group by javascript”,它给出了使用array.reduce的建议,让我们这样做吧

    function flattenSectionsAndSubs(item) {
        return {
            type: item.type, 
            subs: item.sections.reduce((acc, cur) => ([...acc, ...cur.sub]), [])
        }; 
    }
    
    function partition(array, isValid) {
      return array.reduce(([pass, fail], elem) => {
        return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]];
      }, [[], []]);
    }
    
    
        const listTypes = ['ordered-item', 'unordered-item']; 
        function createEmbeddedFromItem(item) {
            const [lists, nonLists] = partition(item.subs, (v) => listTypes.includes(v.type); 
    
          return {
             type: item.type, 
             embedded: [
                 ...nonLists, 
                 {
                    type: "list", 
                    items: lists
                 }
             ]
          }
        }
    
    
    2。现在,对于这些项目中的每一项,我们需要查看它们的子项,并仅对列表项目进行分组。

    为此,我们基本上希望找到所有的`item->sections->sub->type,并将它们过滤到两个数组中。在谷歌上快速搜索如何使用过滤器创建两个数组

    不过,首先,我们需要将节->子节的内容展平,所以让我们这样做吧

    function flattenSectionsAndSubs(item) {
        return {
            type: item.type, 
            subs: item.sections.reduce((acc, cur) => ([...acc, ...cur.sub]), [])
        }; 
    }
    
    function partition(array, isValid) {
      return array.reduce(([pass, fail], elem) => {
        return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]];
      }, [[], []]);
    }
    
    
        const listTypes = ['ordered-item', 'unordered-item']; 
        function createEmbeddedFromItem(item) {
            const [lists, nonLists] = partition(item.subs, (v) => listTypes.includes(v.type); 
    
          return {
             type: item.type, 
             embedded: [
                 ...nonLists, 
                 {
                    type: "list", 
                    items: lists
                 }
             ]
          }
        }
    
    
    我将复制粘贴分区函数到:

    把这一切放在一起,我们就得到了。

    const contentData={
    数据:{
    内容:[{
    键入:“列”,
    章节:[{
    分:[{
    类型:“标题-1”,
    文本:“标题文本”
    }]
    }]
    },
    {
    类型:“acc项目”,
    章节:[{
    分:[{
    类型:“标题-1”,
    文本:“标题文本”
    },
    {
    类型:“订购物品”,
    案文:“项目1”
    },
    {
    类型:“无序项”,
    案文:“项目2”
    }
    ]
    }]
    },
    {
    类型:“acc项目”,
    章节:[{
    分:[{
    类型:“标题-1”,
    正文:“标题正文2”
    }]
    }]
    }
    ]
    }
    }
    函数分区(数组,isValid){
    返回数组.reduce([pass,fail],elem)=>{
    返回是否有效(elem)[
    […通过,要素],失败
    ]:[pass,[…fail,elem];
    }, [
    [],
    []
    ]);
    }
    功能分区和子分区(项目){
    返回{
    类型:item.type,
    subs:item.sections.reduce((acc,cur)=>([…acc,…cur.sub]),[])
    };
    }
    const listTypes=['ordered-item','unordered item'];
    函数createEmbeddedFromItem(项){
    const[list,nonlist]=分区(item.subs,(v)=>listTypes.includes(v.type));
    返回{
    类型:item.type,
    嵌入式:[
    …非名单,
    {
    键入:“列表”,
    项目:清单
    }
    ]
    }
    }
    const groupedData=contentData.data.content.reduce((acc,cur)=>{
    //检查此索引数组是否已存在,如果不存在,请创建它。
    const currentArray=(acc[`cur.type}-group`]和&acc[`cur.type}-group`].items)|[];
    const flatteditem=扁平部分和分段(cur);
    const embeddedItem=createEmbeddedFromItem(FlattedItem);
    返回{
    …acc,
    [`${cur.type}-group`]:{
    类型:`${cur.type}-group`,
    items:[…currentArray,embeddedItem]
    }
    }
    }, {});
    
    console.log(groupedData)您可以存储最后一个项数组以及最后一个嵌入数组,并在找到列类型之前使用它们

    var contentData={data:{content:[{type:“column”,sections:[{sub:[{type:“heading-1”,text:“heading-text”}]},{type:“acc-item”,sections:[{sub:[{type:“heading-1”,text:“heading-text”},{type:“ordered-item”},{type:“unordered item”,text:“item:“item 2”}]},{type:“acc-item:[{sub sub[{类型:“标题-1”,文本:“标题文本2”}]}]}},
    列表=[“已订购项目”、“未订购项目”],
    lastItems,lastEmbedded,
    result=contentData.data.content.reduce((r,{type,sections})=>{
    如果(类型=='列'){
    r、 push({type,embedded:sections.reduce((q,{sub})=>q.concat(sub),[]));
    lastItems=未定义;
    lastEmbedded=未定义;
    返回r;
    }
    if(!lastItems)r.push({type:“acc group”,items:lastItems=[]});
    lastItems.push(…sections.map({sub})=>({
    类型,
    嵌入式:sub.reduce((q,o)=>{