我想将unordered-list-item
和ordered-list-item
分组。
下面是原始结构:
{
data: {
areas: [{
sections: [{
rjf: [
{
type: "unordered-list-item",
text: "Item 1",
},
{
type: "unordered-list-item",
text: "Item 2",
},
{
type: "paragraph",
text: "This is text",
}]
}]
}]
}
}
现在,我要将所有列表项分组到一个新对象中。
所以预期的结构是:
{
data: {
areas: [{
sections: [{
rjf: [
{
type: "list",
items: [{
type: "unordered-list-item",
text: "Item 1",
},
{
type: "unordered-list-item",
text: "Item 2",
}]
},
{
type: "paragraph",
text: "This is text",
}]
}]
}]
}
}
所以我想将所有unordered-list-item and ordered-list-item
移到items
数组,并且像type
这样的后续对象paragraph
不应受到影响。
我用TypeScript创建了一个解决方案,但是代码太长了:
const areas = data.areas;
const listItemTypes = ['unordered-list-item', 'ordered-list-item'];
return areas.map(area => {
return area.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];
}
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;
}, []);
});
});
如何使用lodash实现相同的功能?
****更新****
我尝试过lodash,但似乎没有用。
var content = {
data: {
areas: [{
sections: [{
rjf: [{
type: "unordered-list-item",
text: "Item 1",
},
{
type: "unordered-list-item",
text: "Item 2",
},
{
type: "paragraph",
text: "This is text",
}
]
}]
}]
}
};
var result = content.data.areas.map((area => {
return area.sections.map(section => {
section.rfj = _.groupBy(section.rfj, 'type');
});
}));
document.body.innerHTML = '<pre>' + JSON.stringify(result, null, ' ') + '</pre>';
<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>
答案 0 :(得分:0)
1,000.00 USD
如果您需要更具体的结构,则可能需要对结果进行一些微调,但这应该可以完成大部分工作
答案 1 :(得分:0)
您可以将代码简化为以下形式。
map
和areas
上使用嵌套的sections
。 map
中删除阵列。而是返回具有sections
和rjf
属性的对象(假设两个结构都是只有一个属性的对象)rjf
时,创建2个数组:items
和others
types
数组includes
是否是当前对象的type
,将每个对象分为这2个数组。 list
对象({ type: "list", items }
)和others
数组中的其余对象创建一个数组
const types = ['unordered-list-item', 'ordered-list-item'],
input = {data:{areas:[{sections:[{rjf:[{type:"unordered-list-item",text:"Item 1",},{type:"unordered-list-item",text:"Item 2",},{type:"paragraph",text:"This is text",}]}]}]}}
const areas = input.data.areas.map(a => {
return {
sections: a.sections.map(s => {
const items = [], others = [];
s.rjf.forEach(o =>
types.includes(o.type) ? items.push(o) : others.push(o)
)
return { rjf: [{ type: "list", items }, ...others] }
})
}
})
console.log({ data: { areas } })
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:0)
您可以使用另一种方法,即复制每个对象leven并映射所有数组,并使用分组函数将最后一级分组。
此方法使用amit函数,该函数获取每个级别和起始对象的所有功能。
最后,它将返回具有给定结构和分组项目的新对象。
function copy(source, fn) {
return Object.assign({}, ...Object
.entries(source)
.map(([k, v]) => ({ [k]: fn(v) }))
);
}
function map(array, fn) {
return array.map(fn);
}
function group(array) {
var items;
return array.reduce((r, o) => {
if (listItemTypes.includes(o.type)) {
if (!items) {
items = [];
r.push({ type: 'list', items });
}
items.push(o);
} else {
items = undefined;
r.push(o);
}
return r;
}, []);
}
function iter([fn, ...fns], object) {
return fn ? fn(object, iter.bind(null, fns)) : object;
}
var object = { data: { areas: [{ sections: [{ rjf: [{ type: "unordered-list-item", text: "Item 1" }, { type: "unordered-list-item", text: "Item 2" }, { type: "paragraph", text: "This is text" }] }] }] } },
listItemTypes = ['unordered-list-item', 'ordered-list-item'],
result = iter([copy, copy, map, copy, map, copy, group], object);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }