typescript - Angular 8 - Sortarea unui component de arbore recursiv după tipul valorii
Având următorul obiect:
const data = {
"root": {
"title": "Shapes",
"shapes": { ... },
"description": "All sorts of geometrical whizz"
}
}
Ar trebui să găsesc o modalitate de a sorta acest obiect astfel încât cheile cu obiecte să apară deasupra cheilor cu stringuri, așa cum se vede mai jos:
const data = {
"root": {
"shapes": { ... },
"title": "Shapes",
"description": "All sorts of geometrical whizz"
}
}
Ceea ce am încercat a fost funcția sort():
const sorted = Object.values(root).sort((v) => typeof v === 'object' ? -1 : 1)
Deși acest lucru funcționează pentru a sorta valorile păstrând obiectul rădăcină intact, cheile se pierd în acest nou array sorted...
[
{...},
"Shapes",
"All sorts of geometrical whizz"
]
...în timp ce trebuie păstrat ca un obiect deoarece cheile sunt folosite de un component Tree recursiv, unde sortarea în acest mod este inutilă:
<ng-template *ngFor="let key of Object.keys(data)">
<div *ngIf="typeof key === 'object'>
<button (click)="show(value)">
{{key}}
</button>
<this-template [data]="data[key]">
</div>
<div *ngIf="typeof key === 'string'>
<button (click)="show(value)">
{{key}}
</button>
</div>
</ng-template>
deoarece componenta va continua să se redea pe baza structurii root:
↓ root
|- title
|- > shapes
|- description
în timp ce structura dorită este aceasta:
↓ root
|- > shapes
|- title
|- description
Astfel, pentru a defini problema printr-o singură întrebare;
Cum aș putea să sortezi un obiect după tipul valorii cheii, pentru a reda un component recursiv care să afișeze mai întâi elementele cu obiecte înaintea elementelor cu șiruri de caractere?
Răspuns #1
Folosind Object.entries și un reduce ar trebui să poți obține rezultatul dorit:
const data = {
"root": {
"shapes": { /* ... */ },
"title": "Shapes",
"description": "All sorts of geometrical whizz"
}
}
const sorted = Object.entries(data.root)
.sort(([key, v]) => typeof v === 'object' ? -1 : 1)
.reduce((newObj, [key, v]) => ({ ...newObj, [key]: v }), {})
console.log(sorted)Răspuns #2
O soluție nu foarte elegantă, dar rapidă ar fi
const data = {
"root": {
"title": "Shapes",
"shapes": { a: 'name' },
"description": "All sorts of geometrical whizz"
}
};
const object = {};
Object.values(data.root).forEach((a, i) => {
// console.log(a);
if (typeof(a) === 'object') {
object[Object.keys(data.root)[i]] = a;
}
});
Object.values(data.root).forEach((a, i) => {
// console.log(a);
if (!(typeof(a) === 'object')) {
object[Object.keys(data.root)[i]] = a;
}
});
console.log(object);
