2012-05-10 13 views
26

Tengo dificultades con la sintaxis y la estructura de objetos/matrices JSON.Jerarquización compleja de objetos y matrices

{ 
    "accounting" : [ 
        { "firstName" : "John", 
         "lastName" : "Doe", 
         "age"  : 23 }, 

        { "firstName" : "Mary", 
         "lastName" : "Smith", 
         "age"  : 32 } 
       ],        
    "sales"  : [ 
        { "firstName" : "Sally", 
         "lastName" : "Green", 
         "age"  : 27 }, 

        { "firstName" : "Jim", 
         "lastName" : "Galley", 
         "age"  : 41 } 
       ] 
} 

quiero hacer una estructura anidada de los objetos y las matrices que albergaría la siguiente información:

{ 
"problems": [{ 
    "Diabetes":[{ 
     "medications":[{ 
      "medicationsClasses":[{ 
       "className":[{ 
        "associatedDrug":[{ 
         "name":"asprin", 
         "dose":"", 
         "strength":"500 mg" 
        }], 
        "associatedDrug#2":[{ 
         "name":"somethingElse", 
         "dose":"", 
         "strength":"500 mg" 
        }] 
       }], 
       "className2":[{ 
        "associatedDrug":[{ 
         "name":"asprin", 
         "dose":"", 
         "strength":"500 mg" 
        }], 
        "associatedDrug#2":[{ 
         "name":"somethingElse", 
         "dose":"", 
         "strength":"500 mg" 
        }] 
       }] 
      }] 
     }], 
     "labs":[{ 
      "missing_field": "missing_value" 
     }] 
    }], 
    "Asthma":[{}] 
}]} 

Pero no tengo ni idea de lo que la manera correcta de hacer esto debe ser. ¿Debería estar haciendo objetos de JavaScript? ¿Tiene sentido JSON para este proyecto?

¿Cuál es la sintaxis correcta para configurar algo como esto?

Aquí está mi código hasta ahora:

$(document).ready(function() { 
    $.getJSON('js/orders.json', function(json) { 
     $.each(json.problems, function(index, order) { 
     $('.loadMeds').append('<p>' + order.name + '</p>') 
     }); 
    }); 
}); 
+0

sólo estoy haciendo una prueba local, llamando el archivo JSON con getJSON() en jQuery. Esto es solo para probar en un entorno de producción. Servidor es solo Apache que ejecuta PHP. (No es terriblemente bien informado con cosas del servidor tampoco ...) – Alex

+1

Ejemplo actualizado – Alex

+1

No estoy seguro de dónde quieres llegar con esta pregunta. Debe estructurar los datos de manera que pueda procesarlos fácilmente y eso depende de lo que esté haciendo con los datos ... ¿tiene alguna pregunta * técnica * en particular? De lo contrario, no veo cómo responder esta pregunta. –

Respuesta

21

El primer código es un ejemplo de código JavaScript, que es similar, pero no JSON.JSON no tendría 1) comentarios y 2) la palabra clave var

Usted no tiene comentarios en su JSON, pero se debe quitar el var y empezar así:

orders: { 

Los medios de notación [{}] "objeto en una matriz" y no es lo que necesita en todas partes. No es un error, pero es demasiado complicado para algunos propósitos. AssociatedDrug debería funcionar bien como un objeto:

"associatedDrug": { 
       "name":"asprin", 
       "dose":"", 
       "strength":"500 mg" 
      } 

Además, los laboratorios de objetos vacíos deben llenarse con algo.

Aparte de eso, su código está bien. Usted puede pegarla en Javascript o utilice el método JSON.parse(), o cualquier otro método de análisis sintáctico (por favor don't use eval)

Actualización 2 respondió:

obj.problems[0].Diabetes[0].medications[0].medicationsClasses[0].className[0].associatedDrug[0].name 

devuelve 'aspirina'. Sin embargo, es más adecuado para foreaches en todas partes

+0

Gracias por el consejo sobre eval()! Me aseguraré de evitarlo :) – Alex

+4

@Alex - Una vez que descubras que 'JSON.parse()' no funciona en IE7, hay un método en jQuery para hacerlo en todos los navegadores. '$ .parseJSON()' –

+0

eso es lo que terminé haciendo. Mira mi solución que publiqué. Usé declaraciones anotadas $ .each para captar los datos que estaba buscando. ¡Gracias por la ayuda! – Alex

1

En primer lugar, la elección de una estructura de datos (XML, JSON, YAML) por lo general incluye sólo un problema de legibilidad/tamaño. Por ejemplo

JSON es muy compacto, pero ningún ser humano puede leer con facilidad, muy difícil hacer depuración,

XML es muy grande, pero cada uno puede leer con facilidad/depurarlo,

Yaml está en entre Xml y json.

Pero si desea trabajar con Javascript en gran medida y/o su software realiza una gran cantidad de transferencia de datos entre el navegador-servidor, debe utilizar Json, ya que es puro javascript y muy compacto. Pero no trate de escribirlo en una cadena, use las bibliotecas para generar el código que necesita de un objeto.

Espero que esto ayude.

+0

No sé lo que significa "usar bibliotecas para generar el código que necesita de un objeto". ¿Podría dar un ejemplo? – Alex

+1

@Alex Por ejemplo, cree la matriz/objeto en php, luego use json_encode() para convertirlo en json válido. –

+1

crea un objeto en php, luego envíalo o incrustalo en tu página con el método json_encode(). El proceso se llama serialización de un objeto, lo siento, lo olvidé, dígalo en cuestión; http://www.itnewb.com/tutorial/Introduction-to-JSON-and-PHP/page3 aquí hay un ejemplo – gkaykck

4

Asegúrese de seguir la definición de idioma para JSON. En su segundo ejemplo, la sección:

"labs":[{ 
    "" 
}] 

es válido desde un objeto debe estar compuesto de cero o más pares de valores clave "a" : "b", donde "b" puede ser cualquier valor válido. Algunos analizadores pueden interpretar automáticamente { "" } como { "" : null }, pero este no es un caso claramente definido.

Además, está utilizando un anidado matriz de objetos[{}] un poco. Solo haría esto si:

  1. No hay una buena cadena de "identificador" para cada objeto en la matriz.
  2. Hay una razón clara para tener una matriz sobre un valor-clave para esa entrada.
+0

Labs es un marcador de posición justo ... Este es solo un concepto aproximado. Sé que necesita un valor. – Alex

13

He resuelto con éxito mi problema. Aquí está mi código:

El complejo JSON objeto:

{ 
    "medications":[{ 
      "aceInhibitors":[{ 
       "name":"lisinopril", 
       "strength":"10 mg Tab", 
       "dose":"1 tab", 
       "route":"PO", 
       "sig":"daily", 
       "pillCount":"#90", 
       "refills":"Refill 3" 
      }], 
      "antianginal":[{ 
       "name":"nitroglycerin", 
       "strength":"0.4 mg Sublingual Tab", 
       "dose":"1 tab", 
       "route":"SL", 
       "sig":"q15min PRN", 
       "pillCount":"#30", 
       "refills":"Refill 1" 
      }], 
      "anticoagulants":[{ 
       "name":"warfarin sodium", 
       "strength":"3 mg Tab", 
       "dose":"1 tab", 
       "route":"PO", 
       "sig":"daily", 
       "pillCount":"#90", 
       "refills":"Refill 3" 
      }], 
      "betaBlocker":[{ 
       "name":"metoprolol tartrate", 
       "strength":"25 mg Tab", 
       "dose":"1 tab", 
       "route":"PO", 
       "sig":"daily", 
       "pillCount":"#90", 
       "refills":"Refill 3" 
      }], 
      "diuretic":[{ 
       "name":"furosemide", 
       "strength":"40 mg Tab", 
       "dose":"1 tab", 
       "route":"PO", 
       "sig":"daily", 
       "pillCount":"#90", 
       "refills":"Refill 3" 
      }], 
      "mineral":[{ 
       "name":"potassium chloride ER", 
       "strength":"10 mEq Tab", 
       "dose":"1 tab", 
       "route":"PO", 
       "sig":"daily", 
       "pillCount":"#90", 
       "refills":"Refill 3" 
      }] 
     } 
    ], 
    "labs":[{ 
     "name":"Arterial Blood Gas", 
     "time":"Today", 
     "location":"Main Hospital Lab"  
     }, 
     { 
     "name":"BMP", 
     "time":"Today", 
     "location":"Primary Care Clinic"  
     }, 
     { 
     "name":"BNP", 
     "time":"3 Weeks", 
     "location":"Primary Care Clinic"  
     }, 
     { 
     "name":"BUN", 
     "time":"1 Year", 
     "location":"Primary Care Clinic"  
     }, 
     { 
     "name":"Cardiac Enzymes", 
     "time":"Today", 
     "location":"Primary Care Clinic"  
     }, 
     { 
     "name":"CBC", 
     "time":"1 Year", 
     "location":"Primary Care Clinic"  
     }, 
     { 
     "name":"Creatinine", 
     "time":"1 Year", 
     "location":"Main Hospital Lab" 
     }, 
     { 
     "name":"Electrolyte Panel", 
     "time":"1 Year", 
     "location":"Primary Care Clinic"  
     }, 
     { 
     "name":"Glucose", 
     "time":"1 Year", 
     "location":"Main Hospital Lab" 
     }, 
     { 
     "name":"PT/INR", 
     "time":"3 Weeks", 
     "location":"Primary Care Clinic"  
     }, 
     { 
     "name":"PTT", 
     "time":"3 Weeks", 
     "location":"Coumadin Clinic"  
     }, 
     { 
     "name":"TSH", 
     "time":"1 Year", 
     "location":"Primary Care Clinic"  
     } 
    ], 
    "imaging":[{ 
     "name":"Chest X-Ray", 
     "time":"Today", 
     "location":"Main Hospital Radiology"  
     }, 
     { 
     "name":"Chest X-Ray", 
     "time":"Today", 
     "location":"Main Hospital Radiology"  
     }, 
     { 
     "name":"Chest X-Ray", 
     "time":"Today", 
     "location":"Main Hospital Radiology"  
     } 
    ] 
} 

El código jQuery para agarrar los datos y mostrarlo en mi página web:

$(document).ready(function() { 
var items = []; 

$.getJSON('labOrders.json', function(json) { 
    $.each(json.medications, function(index, orders) { 
    $.each(this, function() { 
     $.each(this, function() { 
      items.push('<div class="row">'+this.name+"\t"+this.strength+"\t"+this.dose+"\t"+this.route+"\t"+this.sig+"\t"+this.pillCount+"\t"+this.refills+'</div>'+"\n"); 
     }); 
    }); 
    }); 

    $('<div>', { 
    "class":'loaded', 
    html:items.join('') 
    }).appendTo("body"); 

}); 

});

+9

Un poco tarde para que yo pueda comentar; pero me parece que todavía estás usando arreglos * mucho *, incluso cuando parece que realmente solo puede haber un objeto. Por ejemplo, su propiedad de 'medicamentos 'de nivel superior es una matriz de un solo objeto. A menos que realmente necesite dar cuenta de múltiples * colecciones * de tipos de medicamentos aquí, dejaría los arreglos por completo. Entonces puedes simplemente usar 'var x = medicines.aceInhibitors' en lugar de' medicamentos [0] .aceInhibitors'. (Para mí, el segundo dice "estoy tomando la propiedad aceInhibitors del * primer objeto * medicamentos" - ¿qué significa primero aquí?) –

+0

No creo que deba poner las propiedades de los tipos med en una matriz. En realidad, hay una forma recomendada de construir JSON para el rendimiento. Consulte el pedido de propiedades https://google.github.io/styleguide/jsoncstyleguide.xml?showone=Property_Ordering_Example#Property_Ordering_Example –

0

Puede intentar utilizar esta función para buscar cualquier objeto en una matriz anidada anidada de matrices de reyes.

Ejemplo

function findTByKeyValue (element, target){ 
     var found = true; 
     for(var key in target) { 
      if (!element.hasOwnProperty(key) || element[key] !== target[key]) { 
       found = false; 
       break; 
      } 
     } 
     if(found) { 
      return element; 
     } 
     if(typeof(element) !== "object") { 
      return false; 
     } 
     for(var index in element) { 
      var result = findTByKeyValue(element[index],target); 
      if(result) { 
       return result; 
      } 
     } 
    }; 

findTByKeyValue(problems,{"name":"somethingElse","strength":"500 mg"}) =====> result equal to object associatedDrug#2