2010-09-13 25 views
3

J'ai un arbre JSON qui contient des nœuds et des enfants - le format est le suivant:manipuler Constructive toute valeur/objet dans un arbre JSON de profondeur inconnue

jsonObject = 
{ 
    id:nodeid_1, 
    children: [ 
    { 
    id:nodeid_2, 
    children:[] 
    }, 
    { 
    id:nodeid_3, 
    children:[ 
    { 
     id:nodeid_4, 
     children:[] 
    }, 
    { 
     id:nodeid_5, 
     children:[] 
    } 
    } 
} 

Je ne sais pas la profondeur de cet arbre, un nœud est capable d'avoir beaucoup d'enfants qui ont aussi beaucoup d'enfants et ainsi de suite.

Mon problème est que j'ai besoin d'ajouter des nœuds dans cet arbre en utilisant un nodeID. Par exemple, une fonction qui peut prendre un nodeID et l'objet node (y compris ses enfants), serait capable de remplacer ce nœud dans l'arbre - ce qui en conséquence deviendrait un arbre plus grand.

Je n'ai rencontré que des fonctions récursives qui me permettent de parcourir tous les nœuds dans un arbre JSON et une modification que j'ai faite de l'une de ces fonctions me renvoie l'objet nœud - mais ne m'aide pas modifier l'arbre d'origine:

var findNode = { 
node:{}, 
find:function(nodeID,jsonObj) { 
    if(typeof jsonObj == "object") { 
     $.each(jsonObj, function(k,v) { 
      if(v == nodeID) { 
       findNode.node = $(jsonObj).eq(0).toArray()[0];   
      } else { 
       findNode.find(nodeID,v); 
      } 
     }); 
    } else { 
     //console.log("jsobObj is not an object"); 
    } 
    } 
} 

qui me permet de faire le test suivant:

findNode.find("nodeid_3",json); 
alert(findNode.node); 

donc, pour résumer - comment puis-je modifier une valeur d'un arbre JSON qui a une profondeur inconnue?

Merci à l'avance

+0

Bonjour, @TJCrowder, 'jsonObject' n'est pas un json, c'est un objet js. –

+0

@ Joe.wang: Je sais. (C'est une de mes bêtes noires, en fait.) Je pense que tu voulais dire cela à Dan. –

Répondre

1

Si vous souhaitez modifier un nœud, comme vous l'avez dit, vous pouvez simplement modifier les propriétés de ce noeud.

var node = findNode.find("nodeid_3",json); 
node.id = "nodeid_3_modified"; 
node.children = []; 

De même, pourquoi utilisez-vous jQuery pour cela?

Voici un autre sans utiliser jQuery devrait fonctionner:

function findNode(object, nodeId) { 
    if (object.id === nodeId) return object; 

    var result; 
    for (var i = 0; i < object.children.length; i++) { 
     result = findNode(object.children[i], nodeId); 
     if (result !== undefined) return result; 
    } 
} 
+0

['jQuery.each'] (http://api.jquery.com/jQuery.each/) (alias' $ .each') est une fonction utilitaire, essentiellement un wrapper de commodité pour 'for..in' quand vous l'appliquer aux objets qui ne sont pas des tableaux. Tout à fait différent de la méthode ['each'] (http://api.jquery.com/each/) des instances jQuery *. Si l'OP utilise jQuery pour quelque chose d'autre, il n'y a pas de mal à utiliser la fonction de commodité (autre que tous les appels de fonction impliqués). –

+0

@ T.J. Crowder: Ouais. Mais pourquoi convertit-il 'jsObj' en un objet jQuery? Les collections et méthodes jQuery sont généralement destinées aux éléments DOM - il doit y avoir un meilleur moyen. –

+0

Je viens de découvrir que toutes les variables que j'utilise sont des pointeurs vers l'arborescence JSON - donc findNode.node est en fait le nœud dans l'arborescence! –

1

Ce ne JSON, il est un Javascript littéral d'objet. JSON est une certaine façon de coder un simple objet Javascript dans une chaîne; votre exemple n'est pas écrit de cette façon. En outre, votre code ne manipule pas les objets JSON (qui sont en fait des chaînes, pas des objets); il manipule les objets Javascript (ce qui est une tâche beaucoup plus simple).

Cela dit, je ne suis pas sûr de ce que votre question réelle est, mais si elle est sur l'ajout de nouveaux éléments au tableau children, vous pouvez utiliser Array.push:

findNode.find("nodeid_3",json); 
findNode.node.children.push(child); 

(Cela suppose que findNode.find effectivement fonctionne, ce que je suis assez sûr qu'il ne fonctionne pas.)

+0

findNode.find() fonctionne, et je viens d'utiliser votre suggestion d'utiliser .children.push (child) - qui a modifié avec succès mon arbre JSON. Merci –