183 votes

Traverser tous les nœuds d'un arbre d'objets JSON avec JavaScript

J'aimerais parcourir un arbre d'objets JSON, mais je ne trouve aucune bibliothèque pour cela. Cela ne semble pas difficile mais j'ai l'impression de réinventer la roue.

Dans XML, il y a tellement de tutoriels montrant comment traverser un arbre XML avec DOM :(

1voto

seung Points 11
var test = {
    depth00: {
        depth10: 'string'
        , depth11: 11
        , depth12: {
            depth20:'string'
            , depth21:21
        }
        , depth13: [
            {
                depth22:'2201'
                , depth23:'2301'
            }
            , {
                depth22:'2202'
                , depth23:'2302'
            }
        ]
    }
    ,depth01: {
        depth10: 'string'
        , depth11: 11
        , depth12: {
            depth20:'string'
            , depth21:21
        }
        , depth13: [
            {
                depth22:'2201'
                , depth23:'2301'
            }
            , {
                depth22:'2202'
                , depth23:'2302'
            }
        ]
    }
    , depth02: 'string'
    , dpeth03: 3
};

function traverse(result, obj, preKey) {
    if(!obj) return [];
    if (typeof obj == 'object') {
        for(var key in obj) {
            traverse(result, obj[key], (preKey || '') + (preKey ? '[' +  key + ']' : key))
        }
    } else {
        result.push({
            key: (preKey || '')
            , val: obj
        });
    }
    return result;
}

document.getElementById('textarea').value = JSON.stringify(traverse([], test), null, 2);

<textarea style="width:100%;height:600px;" id="textarea"></textarea>

0voto

dominik791 Points 275

J'ai créé une bibliothèque pour traverser et éditer des objets JS profondément imbriqués. Découvrez l'API ici : https://github.com/dominik791

Vous pouvez également jouer avec la bibliothèque de manière interactive en utilisant l'application de démonstration : https://dominik791.github.io/obj-traverse-demo/

Exemples d'utilisation : Vous devriez toujours avoir un objet racine qui est le premier paramètre de chaque méthode :

var rootObj = {
  name: 'rootObject',
  children: [
    {
      'name': 'child1',
       children: [ ... ]
    },
    {
       'name': 'child2',
       children: [ ... ]
    }
  ]
};

Le deuxième paramètre est toujours le nom de la propriété qui contient les objets imbriqués. Dans le cas ci-dessus, ce serait 'children' .

Le troisième paramètre est un objet que vous utilisez pour trouver l'objet/les objets que vous voulez trouver/modifier/supprimer. Par exemple, si vous recherchez un objet dont l'identifiant est égal à 1, vous passerez le paramètre { id: 1} comme troisième paramètre.

Et vous le pouvez :

  1. findFirst(rootObj, 'children', { id: 1 }) pour trouver le premier objet avec id === 1
  2. findAll(rootObj, 'children', { id: 1 }) pour trouver tous les objets avec id === 1
  3. findAndDeleteFirst(rootObj, 'children', { id: 1 }) pour supprimer le premier objet correspondant
  4. findAndDeleteAll(rootObj, 'children', { id: 1 }) pour supprimer tous les objets correspondants

replacementObj est utilisé comme dernier paramètre dans deux dernières méthodes :

  1. findAndModifyFirst(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'}) pour changer le premier objet trouvé avec id === 1 à la { id: 2, name: 'newObj'}
  2. findAndModifyAll(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'}) pour changer tous les objets avec id === 1 à la { id: 2, name: 'newObj'}

0voto

vincent Points 395

Nous utilisons balayage de l'objet pour de nombreuses tâches de traitement des données. C'est un outil puissant une fois que vous l'avez compris. Voici comment effectuer une traversée de base

// const objectScan = require('object-scan');

const obj = { foo: 'bar', arr: [1, 2, 3], subo: { foo2: 'bar2' } };

objectScan(['**'], {
  reverse: false,
  filterFn: ({ key, value }) => {
    console.log(key, value);
  }
})(obj);
// => [ 'foo' ] bar
// => [ 'arr', 0 ] 1
// => [ 'arr', 1 ] 2
// => [ 'arr', 2 ] 3
// => [ 'arr' ] [ 1, 2, 3 ]
// => [ 'subo', 'foo2' ] bar2
// => [ 'subo' ] { foo2: 'bar2' }

.as-console-wrapper {max-height: 100% !important; top: 0}

<script src="https://bundle.run/object-scan@13.8.0"></script>

Avis de non-responsabilité : Je suis l'auteur de balayage de l'objet

0voto

Rajaneesh Points 165

Ceci lira tous les noeuds sur une carte.

function readJsonFile() {
    let jsonString = getValueById("testDataContent");
    let jsonObj = JSON.parse(jsonString);
    let jsonElements = [];
    jsonElements = traverse(jsonObj, jsonElements);
    console.log(jsonElements)
}

function traverse(jsonObj, jsonElements) {
    if (jsonObj !== null && typeof jsonObj == "object") {
        Object.entries(jsonObj).forEach(([key, value]) => {

            if (typeof value == "object") {
                var obj = [];
                let map = new Map();
                map.set(key, traverse(value, obj))
                jsonElements.push(map);
            } else {
                var obj = [];
                obj.key = key;
                obj.value = value;
                jsonElements.push(obj);
            }
        });
    } else {

    }
    return jsonElements;
}

-1voto

Ricky Points 613

Vous pouvez obtenir toutes les clés / valeurs et préserver la hiérarchie avec ceci

// get keys of an object or array
function getkeys(z){
  var out=[]; 
  for(var i in z){out.push(i)};
  return out;
}

// print all inside an object
function allInternalObjs(data, name) {
  name = name || 'data';
  return getkeys(data).reduce(function(olist, k){
    var v = data[k];
    if(typeof v === 'object') { olist.push.apply(olist, allInternalObjs(v, name + '.' + k)); }
    else { olist.push(name + '.' + k + ' = ' + v); }
    return olist;
  }, []);
}

// run with this
allInternalObjs({'a':[{'b':'c'},{'d':{'e':5}}],'f':{'g':'h'}}, 'ob')

Il s'agit d'une modification de ( https://stackoverflow.com/a/25063574/1484447 )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X