javascript - data manipulation inside nested array
问题描述
In the below data structure,
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",
}
]
}
]
}]
}]
};
I'm trying to group all the type which as ordered-list-item
& unordered-list-item
into new object. Something like below,
{
"type": 'list',
"items": [
{
"type": "ordered-list-item",
"text": "Ordered Item A",
},
{
"type": "unordered-list-item",
"text": "Ordered Item B",
}
]
}
After so much treble, I came with the below solution. This works fine.
But having an issue, In rjf
if ordered-list-item
& unordered-list-item
not found nothing should be happen unfortunately and empty list
getting added to rjf
.
Below is the code snippet, please help me to fix this issue.
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));
解决方案
你data
有一个非常奇怪的结构,这使得诚实变得更加困难。下面的代码片段使用了一个用于map
所有部分的函数,如果rjf
type 是'unordered-list-item'
or 'ordered-list-item'
,它将把它移动到一个新rjf
的类型list
as 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);
推荐阅读
- ruby-on-rails - Can we change connection dynamicly to Elasticsearch server on Rails App at run time
- python - Django ModelForm 返回 None 而不是 HttpResponse
- elasticsearch - filebeat 无法加载输入
- c# - 在文件中保存和加载数组
- filter - 在 Odoo 中使用激活的过滤器返回视图
- c# - 如何创建 API 端点来获取包括学生在内的部门?
- docker - 使用 docker 容器而不是虚拟机进行测试
- python - Paperboy 抛出错误:TypeError:JSON 对象必须是 str,而不是 'bytes'?
- linux - 如何从 bash 脚本执行 ssh
- android - android Kochava SDK integration crashes the app with google sdk