2
votes

Comment organiser un objet javascript pour de meilleures performances

J'ai un objet de données disant -

const data = {
  'root': [
    {
      id: 1,
      name: 'demo',
      children: [
        {
          id: 2,
          name: 'demo2',
          children: [
            {
              id: 3,
              name: 'demo3',
              children: []
            },
            {
              id: 4,
              name: 'demo4',
              children: [
                {
                  id: 5,
                  name: 'demo5',
                  children: []
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Maintenant ma question est de savoir si je veux effectuer une opération d'ajout / d'édition / de suppression, par exemple, je veux éditer un objet qui a le id = 5 alors je dois visiter root [0] .children [0] .children [1] .children [0] , cette route et terminer la tâche. Je pense que cela coûterait cher et que l'objet pourrait avoir plus de propriétés children imbriquées.

Y a-t-il donc une autre structure par laquelle je peux réorganiser mon objet et effectuer des opérations rapides d'ajout / d'édition / de suppression?


6 commentaires

" Je pense que ce serait cher " deux questions: 1. Pourquoi? 2. Cela va-t-il être significatif d'une manière ou d'une autre?


Vous pouvez soit l'enregistrer sous la forme d'un tableau plat avec une propriété parentId pour chaque élément, soit utiliser la récursivité pour trouver l'objet et le mettre à jour.


@adiga pouvez-vous l'expliquer?


La question est vraiment trop large et difficile à généraliser car différentes structures peuvent être plus faciles à utiliser en fonction du cas d'utilisation. L'utilisation de la structure montrée est souvent plus facile


Je veux juste ajouter / modifier / supprimer du contenu de l'objet. Mais si je veux ajouter quelque chose à des enfants profonds, je dois rendre visite à la racine. Je voulais quelque chose de linéaire. @charlietfl


@SajeebAhamed quelque chose comme le tableau dans cette question


3 Réponses :


1
votes

Ce n'est pas si cher et peut-être que cela ne vaut pas la peine d '«améliorer» quoi que ce soit à moins de mesurer et d'avoir des preuves tangibles que cette partie de votre programme est lente.

Si vous vouliez vraiment accélérer les choses, vous pouvez créer deuxième structure de données avec des références à tous les éléments. Par exemple:

const refs = {
  1: data['root'][0],
  2: data['root'][0]['children'][0],
  3: ...
}

et chaque fois que vous vouliez l'élément avec l'id 2, vous feriez simplement refs [2] . Vous pouvez bien sûr générer cet objet refs automatiquement et non à la main.


0 commentaires

0
votes

au lieu de la structure imbriquée, définissez la clé étrangère (fId) comme ceci:

const data = {
      'root': [
        {
            id: 1,
            name: 'demo',
            fId:[]
        },
        {
            id: 2,
            name: 'demo2',
            fId:[1]
        },
        {
            id: 3,
            name: 'demo3',
            fId:[2]
        },
        {
            id: 4,
            name: 'demo4',
            fId:[3]
        },
        {
            id: 5,
            name: 'demo5',
            fId:[4]
        }
      ]
    }


2 commentaires

Que faire si je souhaite supprimer un nœud parent? Cela doit également trouver et supprimer tous les enfants.


Basé sur le travail, c'est différent, dans le pire des cas dans la suppression, il faut écrire une boucle pour supprimer le parent



2
votes

Étant donné que les valeurs id sont uniques, vous pouvez gérer une Map (ou un objet) qui fait directement référence aux entrées, quel que soit leur emplacement dans le parent / enfant structure. La structure parent / enfant contiendrait simplement l ' id des enfants plutôt que l'objet enfant réel, par exemple:

function removeEntry(data, id) {
    const entry = data[id];
    for (const childId of entry.children) {
        removeEntry(data, childId);
    }
    delete data[id]; // The object version
    // Or: data.delete(id); // The Map version
}

L'accès par ID est simplement des données [id] .

Cet exemple utilise un objet avec des clés de chaîne numérique (elles sont écrites sous forme de nombres littéraux ci-dessus, mais les noms de propriété sont toujours des chaînes [ou des symboles]). Mais vous pouvez utiliser une Carte à la place:

const data = new Map([
    [1, {
        id: 1,
        name: 'demo',
        children: [2]
    }],
    [2, {
        id: 2,
        name: 'demo2',
        children: [3, 4]
    }],
    [3, {
        id: 3,
        name: 'demo3',
        children: []
    }],
    [4, {
        id: 4,
        name: 'demo4',
        children: [5]
    }],
    [5, {
        id: 5,
        name: 'demo5',
        children: []
    }]
]);

Ces clés de carte sont en fait des nombres. L'accès par ID est simplement data.get (id) et data.set (id, newEntry) .

Vous voudrez avoir des fonctions pour opérer sur cette structure (ajouter, supprimer, déplacer). Vous pouvez utiliser des fonctions autonomes qui acceptent la structure, par exemple:

const data = {
    1: {
        id: 1,
        name: 'demo',
        children: [2]
    },
    2: {
        id: 2,
        name: 'demo2',
        children: [3, 4]
    },
    3: {
        id: 3,
        name: 'demo3',
        children: []
    },
    4: {
        id: 4,
        name: 'demo4',
        children: [5]
    },
    5: {
        id: 5,
        name: 'demo5',
        children: []
    }
};

... ou vous pouvez regrouper tout cela dans une classe . p>


2 commentaires

Cela signifie que les opérations d'ajout / d'édition sont linéaires (il suffit de le pousser et de pousser l'id dans le tableau des enfants du parent) mais que l'opération de suppression nécessite que tous les enfants soient supprimés de manière récursive.


@SajeebAhamed - L'ajout n'est pas linéaire, c'est presque constant. La suppression se fait le plus facilement avec la récursivité, oui. (Cela pourrait être fait avec une boucle, mais c'est plus compliqué. Sauf si vous vous attendez à une imbrication de sorte que vous répétiez plus de 30 000 fois, vous n'avez pas à vous soucier de la récursivité sur les moteurs modernes.)