Estoy trabajando con un objeto JSON que puede tener una propiedad ids en cualquier hoja. Quiero atravesar el objeto y encontrar todas las instancias de la ids propiedad y almacenar cada una de las id en una colección.

Burló hasta un Objeto JSON (el ids propiedad podría ser mucho más profundo de propiedad de las ubicaciones).

{
  "id": "b38a683d-3fb6-408f-9ef6-f4b853ed1193",
  "foo": {
    "ids": [
      {
        "id": "bd0bf3bd-d6b9-4706-bfcb-9c867e47b881"
      },
      {
        "id": "d1cc529d-d5d2-4460-b2bb-acf24a7c5999"
      },
      {
        "id": "b68d0c8c-548e-472f-9b01-f25d4b199a71"
      }
    ],
    "baz": "super"
  },
  "bar": {
    "ids": [
      {
        "id": "bd0bf3bd-d6b9-4706-bfcb-9c867e47b881"
      },
      {
        "id": "d1cc529d-d5d2-4460-b2bb-acf24a7c5999"
      },
      {
        "id": "b68d0c8c-548e-472f-9b01-f25d4b199a71"
      }
    ]
  }
}

Estoy usando el siguiente código para recorrer el anterior JSON.

var jsonFile = require('./file_test.json'); //the above in my local directory

function traverse(obj, ids) {
  for (var prop in obj) {
    if (typeof obj[prop] == "object" && obj[prop]) {
      if (prop == 'ids') {
        for (var i = obj[prop].length - 1; i >= 0; i--) {
          ids.push(obj[prop][i]._id);
        };
      }
      traverse(obj[prop], ids);
    }
  }
}

var ids = new Array();
traverse(jsonFile, ids);

console.log('ids', ids);

Las anteriores redes de los siguientes:

ids
[
  'b68d0c8c-548e-472f-9b01-f25d4b199a71',
  'd1cc529d-d5d2-4460-b2bb-acf24a7c5999',
  'bd0bf3bd-d6b9-4706-bfcb-9c867e47b881',
  'b68d0c8c-548e-472f-9b01-f25d4b199a71',
  'd1cc529d-d5d2-4460-b2bb-acf24a7c5999',
  'bd0bf3bd-d6b9-4706-bfcb-9c867e47b881'
]

Mientras mi código funciona no estoy convencido de que estoy haciendo de este el más eficiente o de la mejor manera. Hay una mejor manera de encontrar todas las instancias de la ids propiedad? Tal vez sin la necesidad de pasar de una matriz pero volviendo uno? O la creación de una devolución de llamada con un ids matriz?

InformationsquelleAutor ahsteele | 2013-04-13

4 Comentarios

  1. 6

    Si los datos fue en realidad una cadena JSON, y no un objeto de JavaScript, usted podría tener algo como:

    //assuming `json` is the data string
    var ids = [];
    var data = JSON.parse(json, function(key, value) {
        if (key === "id") 
            ids.push(value);
    
        return value;
    });

    Ver reviver en JSON.analizar método.

  2. 3

    lo que tiene está bien, pero este es un poco más corto y utiliza el .función de mapa:

    var jsonFile = require('./file_test.json'); //the above in my local directory
    function traverse(obj) {
        var ids = [];
        for (var prop in obj) {
            if (typeof obj[prop] == "object" && obj[prop]) {
                if (prop == 'ids') {
                    ids = obj[prop].map(function(elem){
                       return elem.id;
                   })
                }
                ids =ids.concat(traverse(obj[prop]));
            }
        }
        return ids;
    }
    
    var ids =traverse(jsonFile);
    
    console.log('ids', ids);
    • Me sonó como identificadores pueden ser anidados en identificadores, así que me fui de recorrer siguiendo el si.
  3. 0

    Lo que, básicamente, tratando de hacer es un árbol de búsqueda de este objeto JSON, estoy en lo cierto? Entonces, si asumimos que ids es siempre una hoja y luego no necesitamos traverse los nodos como sabemos que en la hoja y contendrá lo que queremos.

    • Cambiar el if {...} traverse a if {...} else {traverse}

    Si es posible cambiar la estructura de datos de ids a una lista de cadenas en lugar de una lista de objetos a continuación, usted será capaz de salvar a la iteración a través de la matriz y sólo de mezcla en el ids matriz pasada, pero depende completamente del contexto y de si o no usted puede hacer este cambio!

    Lo siento, no estoy de más ayuda!

    • Sí, básicamente, un árbol de búsqueda del objeto JSON. Por desgracia, no se puede cambiar el id de una lista de cadenas.
  4. 0

    Suponiendo ES5 está disponible de forma nativa o mediante un calza:

    function gimmeIds(obj) {
        return Object.keys(obj||{})
            .reduce(function(ids, key) {
                if(key === 'ids') {
                    return ids.concat(obj[key].map(function(idObj) {
                        return idObj.id;
                    }));
                }
    
                if(obj[key] && typeof obj[key] == 'object') {
                    return ids.concat(gimmeIds(obj[key]));
                }
    
                return ids;
            }, []);
    }

Dejar respuesta

Please enter your comment!
Please enter your name here