如何将字符串数组转换为具有多个元素的对象数组
how to transform strin array in to array of objects with multiple elements
我有这个数组:
data: [
‘big text 1 here.’,
‘big text 2 here followed by list:’,
'-this is list item;',
'-this is another list item;',
‘big text 3 here followed by list:’,
'-this is list item;',
'-this is another list item;',
'-this is another list item;',
‘big text 4 here.’
],
我想把它变成类似这样的东西:
data: [
{
text: ‘big text 1 here.’
list: []
},
{
text: ‘big text 2 here followed by list:’
list: [
'-this is list item;',
'-this is another list item;'
]
},
{
text: ‘big text 3 here followed by list:’
list: [
'-this is list item;',
'-this is another list item;',
'-this is another list item;',
]
},
{
text: ‘big text 4 here.’
list: []
},
],
我正在尝试通过这种方式实现这一目标
interface item {
text: string;
list: string[];
};
const newArr: item[] = [];
this.item.content.forEach((x, i) => {
if(x.startsWith('-') && x.endsWith(';')) {
//this is bullet list, need to add that to the previous item...
} else {
newArr.push({ text: x, list: []});
}
});
我不确定我这样做是否正确,因为我无法想到如何访问 newArr 中的上一个元素;任何想法如何以正确的方式做到这一点?
这是我想要基于该数据的输出:
<p>big text 1 here</p>
<p>big text 2 here followed by list:</p>
<ul>
<li>this is list item</li>
<li>this is another list item</li>
</ul>
<p>big text 3 here followed by list</p>
<ul>
<li>this is list item</li>
<li>this is another list item</li>
<li>this is another list item</li>
<p>big text 4 here</p>
只是说您的字符串没有正确的引号,’
和 '
不一样,’
不适用于字符串。
为此我会使用 Array.reduce
interface DataItem {
text: string
list: string[]
}
function isListItem(item: string): boolean {
return item.startsWith('-') && item.endsWith(';')
}
const transformedData = data.reduce<DataItem[]>((acc, item) => {
// if item is list item
if (isListItem(item)) {
// get last DataItem from acc
const lastDataItem = acc[acc.length - 1]
// and use it as list item's parent
if (lastDataItem) {
lastDataItem.list.push(item)
} else {
console.error(`Parent text not found for list item ${item}`)
}
return acc
}
// if item is not list item, use it as new parent/DataItem
const dataItem: DataItem = {
text: item,
list: []
}
return [...acc, dataItem]
}, [])
您可以尝试以下代码段
let data = [
'big text 1 here.',
'big text 2 here followed by list:',
'-this is list item;',
'-this is another list item;',
'big text 3 here followed by list:',
'-this is list item;',
'-this is another list item;',
'-this is another list item;',
'big text 4 here.'
];
function format_array_to_object(data) {
let new_data = [];
let previous_data = {};
data.forEach( function( item, key ){
if ( item.trim().charAt(0) === '-' ) {
previous_data.list.push( item );
} else {
if ( Object.keys(previous_data).length !== 0 ) {
new_data.push(previous_data);
previous_data = {};
let current_elem = { text: item, list:[] };
previous_data = current_elem;
} else {
let current_elem = { text: item, list:[] };
previous_data = current_elem;
}
if ( ( key + 1 ) === data.length ) {
new_data.push(previous_data);
}
}
} );
return new_data;
}
console.log(format_array_to_object(data));
我会选择 ngTemplateOutlet 选项来根据您的列表数组生成 li。
<ul *ngFor="let item of data">
<ng-container
*ngTemplateOutlet="
!(item.startsWith('-') && item.endsWith(';')) ? ulTemplate : bulletItem;
context: { $implicit: item }
"
>
</ng-container>
</ul>
<ng-template #ulTemplate let-item>
<li>{{ item }}</li>
</ng-template>
<ng-template #bulletItem let-item>
<ul>
<li>{{ item }}</li>
</ul >
</ng-template>
现在,这样您就可以根据您的起始字符重新获得正确的ng-template。
在此 link Stackblitz Link
中完成演示
我有这个数组:
data: [
‘big text 1 here.’,
‘big text 2 here followed by list:’,
'-this is list item;',
'-this is another list item;',
‘big text 3 here followed by list:’,
'-this is list item;',
'-this is another list item;',
'-this is another list item;',
‘big text 4 here.’
],
我想把它变成类似这样的东西:
data: [
{
text: ‘big text 1 here.’
list: []
},
{
text: ‘big text 2 here followed by list:’
list: [
'-this is list item;',
'-this is another list item;'
]
},
{
text: ‘big text 3 here followed by list:’
list: [
'-this is list item;',
'-this is another list item;',
'-this is another list item;',
]
},
{
text: ‘big text 4 here.’
list: []
},
],
我正在尝试通过这种方式实现这一目标
interface item {
text: string;
list: string[];
};
const newArr: item[] = [];
this.item.content.forEach((x, i) => {
if(x.startsWith('-') && x.endsWith(';')) {
//this is bullet list, need to add that to the previous item...
} else {
newArr.push({ text: x, list: []});
}
});
我不确定我这样做是否正确,因为我无法想到如何访问 newArr 中的上一个元素;任何想法如何以正确的方式做到这一点?
这是我想要基于该数据的输出:
<p>big text 1 here</p>
<p>big text 2 here followed by list:</p>
<ul>
<li>this is list item</li>
<li>this is another list item</li>
</ul>
<p>big text 3 here followed by list</p>
<ul>
<li>this is list item</li>
<li>this is another list item</li>
<li>this is another list item</li>
<p>big text 4 here</p>
只是说您的字符串没有正确的引号,’
和 '
不一样,’
不适用于字符串。
为此我会使用 Array.reduce
interface DataItem {
text: string
list: string[]
}
function isListItem(item: string): boolean {
return item.startsWith('-') && item.endsWith(';')
}
const transformedData = data.reduce<DataItem[]>((acc, item) => {
// if item is list item
if (isListItem(item)) {
// get last DataItem from acc
const lastDataItem = acc[acc.length - 1]
// and use it as list item's parent
if (lastDataItem) {
lastDataItem.list.push(item)
} else {
console.error(`Parent text not found for list item ${item}`)
}
return acc
}
// if item is not list item, use it as new parent/DataItem
const dataItem: DataItem = {
text: item,
list: []
}
return [...acc, dataItem]
}, [])
您可以尝试以下代码段
let data = [
'big text 1 here.',
'big text 2 here followed by list:',
'-this is list item;',
'-this is another list item;',
'big text 3 here followed by list:',
'-this is list item;',
'-this is another list item;',
'-this is another list item;',
'big text 4 here.'
];
function format_array_to_object(data) {
let new_data = [];
let previous_data = {};
data.forEach( function( item, key ){
if ( item.trim().charAt(0) === '-' ) {
previous_data.list.push( item );
} else {
if ( Object.keys(previous_data).length !== 0 ) {
new_data.push(previous_data);
previous_data = {};
let current_elem = { text: item, list:[] };
previous_data = current_elem;
} else {
let current_elem = { text: item, list:[] };
previous_data = current_elem;
}
if ( ( key + 1 ) === data.length ) {
new_data.push(previous_data);
}
}
} );
return new_data;
}
console.log(format_array_to_object(data));
我会选择 ngTemplateOutlet 选项来根据您的列表数组生成 li。
<ul *ngFor="let item of data">
<ng-container
*ngTemplateOutlet="
!(item.startsWith('-') && item.endsWith(';')) ? ulTemplate : bulletItem;
context: { $implicit: item }
"
>
</ng-container>
</ul>
<ng-template #ulTemplate let-item>
<li>{{ item }}</li>
</ng-template>
<ng-template #bulletItem let-item>
<ul>
<li>{{ item }}</li>
</ul >
</ng-template>
现在,这样您就可以根据您的起始字符重新获得正确的ng-template。 在此 link Stackblitz Link
中完成演示