嵌套数组中的数据操作

时间:2019-04-30 06:51:42

标签: javascript typescript

在下面的数据结构中,

data = {
  data: [{
    areas: [{
      sections: [{
          rjf: [{
            type: 'heading-1'
            text: 'Sample Heading',
          }]
        },
        {
          rjf: [{
              type: 'paragraph',
              depth: 0,
              text: 'This website is offered to you by:',
              inlineStyleRanges: [],
              inlineEntityRanges: []
            },
            {
              "type": "ordered-list-item",
              "text": "Ordered Item A",
            },
            {
              "type": "unordered-list-item",
              "text": "Ordered Item B",
            },
            {
              type: 'paragraph',
              depth: 0,
              text: 'This website is offered to you by:',
              inlineStyleRanges: [],
              inlineEntityRanges: []
            },
            {
              "type": "ordered-list-item",
              "text": "Ordered Item A",
            },
            {
              "type": "unordered-list-item",
              "text": "Ordered Item B",
            }
          ]
        }
      ]
    }]
  }]
};

我正在尝试将ordered-list-itemunordered-list-item的所有类型归为新对象。像下面这样

{
    "type": 'list',
    "items": [
      {
        "type": "ordered-list-item",
        "text": "Ordered Item A",
      },
      {
        "type": "unordered-list-item",
        "text": "Ordered Item B",
      }
    ]
  }

经过了如此多的高音之后,我提出了以下解决方案。这很好。 但是有一个问题,在rjf中,如果找不到ordered-list-itemunordered-list-item,应该没有任何事情发生,并且将空list添加到rjf中。

下面是代码段,请帮助我解决此问题。

const data = {
  data: [{
    areas: [{
      sections: [{
          rjf: [{
            text: 'Sample Heading',
          }]
        },
        {
          rjf: [{
              type: 'paragraph',
              depth: 0,
              text: 'This website is offered to you by:',
              inlineStyleRanges: [],
              inlineEntityRanges: []
            },
            {
              "type": "ordered-list-item",
              "text": "Ordered Item A",
            },
            {
              "type": "unordered-list-item",
              "text": "Ordered Item B",
            },
            {
              type: 'paragraph',
              depth: 0,
              text: 'This website is offered to you by:',
              inlineStyleRanges: [],
              inlineEntityRanges: []
            },
            {
              "type": "ordered-list-item",
              "text": "Ordered Item A",
            },
            {
              "type": "unordered-list-item",
              "text": "Ordered Item B",
            }
          ]
        }
      ]
    }]
  }]
};
const moveToNewObject = (data) => {
  const sections = data[0].areas[0].sections;
  sections.forEach(data => {
    let list = data.rjf;
    let a = list.map((entry, index) => {
      return { ...entry,
        index,
        use: entry.type !== 'unordered-list-item' && entry.type !== 'ordered-list-item'
      }
    }).filter(entry => entry.use).map((entry, index, entries) => {
      const end = index < entries.length - 1 ? entries[index + 1].index : list.length - entry.index;
      return [{
        type: entry.type,
        text: entry.text
      }, {
        type: 'list',
        items: list.slice(entry.index + 1, entry.index + end)
      }]
    });
    console.log(a);
  });
}
console.log(moveToNewObject(data.data));

2 个答案:

答案 0 :(得分:1)

您的data的结构很怪异,很难说实话。下面的代码段使用了一个在您所有部分上使用map的函数,并且如果rjf类型是'unordered-list-item''ordered-list-item',它将移动到新的rjf类型list作为items的类型。希望这就是您想要的。

如果您想要更清晰的代码格式,这是一个小提琴: https://jsfiddle.net/qce2vLr3/

const data = {
  data: [
    {
      areas: [
        {
          sections: [
            {
              rjf: [
                {
                  text: 'Sample Heading',
                }
              ]
            },
            {
              rjf: [
                {
                  type: 'paragraph',
                  depth: 0,
                  text: 'This website is offered to you by:',
                  inlineStyleRanges: [],
                  inlineEntityRanges: []
                },
                {
                  "type": "ordered-list-item",
                  "text": "Ordered Item A",
                },
                {
                  "type": "unordered-list-item",
                  "text": "Ordered Item B",
                }
              ]
            }
          ]
        }
      ]
    }
  ]
};

const moveToNewObject = (data) => {
	const sections = data[0].areas[0].sections; // why is data an array?
  return sections.map((section) => {
  	if (section.rjf) {
    	const looseItems = section.rjf.filter((rjf) => rjf.type && ['ordered-list-item', 'unordered-list-item'].includes(rjf.type));
      if (looseItems.length) {
      	return { 
        	rjf: [
          	...section.rjf,
          	{ 
          		type: 'list',
            	items: looseItems 
          	}
          ].filter((rjf) => rjf.type && !['ordered-list-item', 'unordered-list-item'].includes(rjf.type))
        }
      }
      return section;
    }
    return section;
  })
}

data.data[0].areas[0].sections = moveToNewObject(data.data);
console.log(data.data);

更新

以下是一种通过多个标题将列表“分组”的解决方案:https://jsfiddle.net/pkLyd0gh/

const data = {
  data: [
    {
      areas: [
        {
          sections: [
            {
              rjf: [
                {
                  text: 'Sample Heading',
                }
              ]
            },
            {
              rjf: [
                {
                  "type": "heading-1",
                  "text": "A title",
                },
                {
                  "type": "ordered-list-item",
                  "text": "Ordered Item A",
                },
                {
                  "type": "unordered-list-item",
                  "text": "Ordered Item B",
                },
                {
                  "type": "heading-2",
                  "text": "A title",
                },
                {
                  "type": "ordered-list-item",
                  "text": "Ordered Item C",
                },
                {
                  "type": "unordered-list-item",
                  "text": "Ordered Item D",
                }
              ]
            }
          ]
        }
      ]
    }
  ]
};

const reformattedSections = (data) => {
	const sections = data[0].areas[0].sections;
  const listItemTypes = ['unordered-list-item', 'ordered-list-item'];
  return sections.map((section) => {
  	let lastHeadingIndex = -1;
  	return section.rjf.reduce((acc, current, index) => {
    	if (!current.type || !listItemTypes.includes(current.type)) {
      	lastHeadingIndex = acc.length;
        return [...acc, current]
      }
      else {
      	let listObject = acc.find((el, i) => i > lastHeadingIndex && i < index && el.type === 'list');
        if (!listObject) {
        	listObject = {
          	type: 'list',
            items: [current]
          }
          return [...acc, listObject];
        }
        listObject.items = [...listObject.items, current];
      	return acc;
      }
    }, [])
  })
}

data.data[0].areas[0].sections = reformattedSections(data.data);
console.log('sections', data.data);

答案 1 :(得分:0)

slice是对数组而不是对象的方法。您代码中的DATA是一个对象

const a ={a:1,b:2,c:3,d:4}
const b =[1,2,3,4]

//console.log(a.slice(1,3)) //this will return the error    
console.log(b.slice(1,3))

希望有帮助。