Tengo esta matriz:
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.' ],Quiero convertirlo en algo como:
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: [] }, ],Estoy tratando de lograr esto de esta manera
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: []}); } });No estoy seguro si lo estoy haciendo de la manera correcta, porque no se me ocurre cómo acceder al elemento anterior en newArr; ¿Alguna idea de cómo hacerlo de manera adecuada?
Ese es el resultado que quiero tener basado en esos datos:
<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>Usaría Array.reduce para esto
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] }, [])Iría por la opción ngTemplateOutlet para generar li en función de su matriz de lista.
<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>Ahora, de esta manera, ha redirigido la plantilla ng correcta en función de su carácter de inicio. Demo completa en este enlace Stackblitz Link
Puede probar el siguiente fragmento a continuación
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));