Pregunta

Cuando se genera manualmente una matriz o un objeto JSON, a menudo es más fácil dejar una coma al final del último elemento de la matriz. Por ejemplo, el código para generar un conjunto de cadenas puede parecer (en un pseudocódigo de C ++):

s.append("[");
for (i = 0; i < 5; ++i) {
    s.appendF("\"%d\",", i);
}
s.append("]");

dándote una cadena como

[0,1,2,3,4,5,]

¿Está esto permitido?

¿Fue útil?

Solución

Desafortunadamente, la especificación JSON no permite una coma al final. Hay algunos navegadores que lo permitirán, pero generalmente debes preocuparte por todos los navegadores.

En general, trato de solucionar el problema y agrego la coma antes del valor real, por lo que terminas con un código que se ve así:

s.append("[");
for (i = 0; i < 5; ++i) {
  if (i) s.append(","); // add the comma only if this isn't the first entry
  s.appendF("\"%d\"", i);
}
s.append("]");

Esa línea de código adicional en tu bucle for no es cara ...

Otra alternativa que he usado al generar una estructura en JSON desde un diccionario de alguna forma es siempre agregar una coma después de cada entrada (como lo está haciendo arriba) y luego agregar una entrada ficticia al final que no tenga finalización. coma (pero eso es simplemente perezoso; - >).

Desafortunadamente, no funciona bien con una matriz.

Otros consejos

No. La especificación JSON, tal como se mantiene en http://json.org , no permite comas finales. Por lo que he visto, algunos analizadores pueden permitirlos silenciosamente al leer una cadena JSON, mientras que otros arrojan errores. Para la interoperabilidad, no debes incluirlo.

El código anterior se podría reestructurar, ya sea para eliminar la coma final al agregar el terminador de la matriz o para agregar la coma antes de los elementos, omitiendo eso para el primero.

Simple, barato, fácil de leer, y siempre funciona sin importar las especificaciones.

$delimiter = '';
for ....  {
    print $delimiter.$whatever
    $delimiter = ',';
}

La asignación redundante a $ delim es un precio muy pequeño a pagar. También funciona igual de bien si no hay un bucle explícito sino fragmentos de código separados.

Se permiten comas finales en JavaScript, pero no funcionan en IE. Las especificaciones JSON sin versión de Douglas Crockford no las permitían, y debido a que era sin versión, no se suponía que esto cambiara. La especificación JSON de ES5 les permitió una extensión, pero el RFC 4627 de Crockford no lo hizo, y ES5 se revirtió para rechazarlos. Firefox hizo lo mismo. Internet Explorer es la razón por la que no podemos tener cosas buenas.

Como ya se ha dicho, la especificación JSON (basada en ECMAScript 3) no permite una coma final. ES > = 5 lo permite, por lo que puede usar esa notación en JS puro. Se ha discutido acerca de, y algunos analizadores lo hicieron apoyándolo ( http: // bolinfest. com / essays / json.html , http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/ ), pero es el hecho específico (como se muestra en < a href = "http://json.org/" rel = "noreferrer"> http://json.org/ ) que no debería funcionar en JSON. Esa cosa dijo ...

... Me pregunto por qué nadie señaló que realmente puedes dividir el bucle en la iteración 0 y usar la coma al principio en lugar de arrastrar una para eliminar el olor del código de comparación y cualquier sobrecarga de rendimiento real en el bucle, lo que resulta en un código que en realidad es más corto, más simple y más rápido (debido a que no hay bifurcaciones / condicionales en el bucle) que otras soluciones propuestas.

Por ejemplo, (en un pseudocódigo de estilo C similar al código propuesto por OP):

s.append("[");
// MAX == 5 here. if it's constant, you can inline it below and get rid of the comparison
if ( MAX > 0 ) {
    s.appendF("\"%d\"", 0); // 0-th iteration
    for( int i = 1; i < MAX; ++i ) {
        s.appendF(",\"%d\"", i); // i-th iteration
    }
}
s.append("]");

Los codificadores PHP pueden querer revisar implode () . Esto hace que una matriz se una con una cadena.

De los docs ...

$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone

Curiosamente, tanto C & amp; C ++ (y creo que C #, pero no estoy seguro) permite específicamente la coma al final, exactamente por el motivo: es mucho más fácil generar listas mediante programación. No estoy seguro de por qué JavaScript no siguió su ejemplo.

Usa JSON5. No uses JSON.

  • Los objetos y las matrices pueden tener comas al final
  • Las claves de los objetos no pueden estar entre comillas si son identificadores válidos
  • Las cadenas pueden ser entre comillas simples
  • Las cadenas se pueden dividir en varias líneas
  • Los números pueden ser hexadecimales (base 16)
  • Los números pueden comenzar o terminar con un punto decimal (al principio o al final).
  • Los números pueden incluir Infinito e -Infinito.
  • Los números pueden comenzar con un signo más (+) explícito.
  • Se permiten comentarios en línea (línea única) y en bloque (línea múltiple).

http://json5.org/

https://github.com/aseemk/json5

De acuerdo con la Especificación de la clase JSONArray :

  • Puede aparecer una (coma) adicional justo antes del soporte de cierre.
  • El valor nulo se insertará cuando haya, (coma) elision.

Entonces, como lo entiendo, debería permitirse escribir:

[0,1,2,3,4,5,]

Pero podría suceder que algunos analizadores devuelvan el 7 como recuento de elementos (como IE8 como señaló Daniel Earwicker) en lugar de los 6 esperados.


Editado:

Encontré este JSON Validator que valida una cadena JSON contra RFC 4627 (La aplicación / json tipo de medios para la notación de objetos de JavaScript) y en contra de la especificación de idioma de JavaScript. En realidad, aquí una matriz con una coma final se considera válida solo para JavaScript y no para la especificación RFC 4627.

Sin embargo, en la especificación RFC 4627 se establece que:

  

2.3. Arrays

     

Una estructura de matriz se representa como corchetes que rodean a cero   o más valores (o elementos). Los elementos están separados por comas.

array = begin-array [ value *( value-separator value ) ] end-array

Para mí esto es nuevamente un problema de interpretación. Si escribe que los elementos están separados por comas (sin indicar algo sobre casos especiales, como el último elemento), se puede entender de ambas maneras.

P.S. RFC 4627 no es un estándar (como se indica explícitamente), y ya está obsoleto por RFC 7159 (que es un estándar propuesto) RFC 7159

A partir de mi experiencia pasada, descubrí que los diferentes navegadores manejan las comas finales en JSON de manera diferente.

Tanto Firefox como Chrome lo manejan bien. Pero IE (todas las versiones) parece romperse. Quiero decir realmente romper y dejar de leer el resto del guión.

Teniendo esto en cuenta, y también el hecho de que siempre es bueno escribir código compatible, sugiero que realicen un esfuerzo extra para asegurarse de que no haya una coma al final.

:)

Mantengo un recuento actual y lo comparo con un recuento total. Si el recuento actual es menor que el recuento total, muestro la coma.

Puede que no funcione si no tienes un recuento total antes de ejecutar la generación JSON.

Nuevamente, si estás usando PHP 5.2.0 o superior, simplemente puedes formatear tu respuesta usando la API JSON incorporada.

Con JSON relajado, puede tener comas al final, o simplemente dejar las comas afuera . Son opcionales.

No hay ninguna razón para que las comas estén presentes para analizar un documento tipo JSON.

Eche un vistazo a la especificación JSON relajada y verá cuán 'ruidosa' es la especificación JSON original. Demasiadas comas y comillas ...

http://www.relaxedjson.org

También puedes probar tu ejemplo usando este analizador RJSON en línea y verlo como se analiza correctamente.

http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D

Por lo general, recorro la matriz y adjunto una coma después de cada entrada en la cadena. Después del bucle, vuelvo a eliminar la última coma.

Tal vez no sea la mejor, pero menos costoso que comprobar cada vez que es el último objeto del circuito, supongo.

No se recomienda, pero aún puedes hacer algo como esto para analizarlo.

jsonStr = '[0,1,2,3,4,5,]';
let data;
eval('data = ' + jsonStr);
console.log(data)

Hay una forma posible de evitar una rama if en el bucle.

s.append("[ "); // there is a space after the left bracket
for (i = 0; i < 5; ++i) {
  s.appendF("\"%d\",", i); // always add comma
}
s.back() = ']'; // modify last comma (or the space) to right bracket

Dado que se utiliza un for-loop para recorrer una matriz, o una estructura de datos iterable similar, podemos usar la longitud de la matriz como se muestra,

awk -v header="FirstName,LastName,DOB" '
  BEGIN {
    FS = ",";
    print("[");
    columns = split(header, column_names, ",");
  }
  { print("  {");
    for (i = 1; i < columns; i++) {
      printf("    \"%s\":\"%s\",\n", column_names[i], $(i));
    }
    printf("    \"%s\":\"%s\"\n", column_names[i], $(i));
    print("  }");
  }
  END { print("]"); } ' datafile.txt

Con datafile.txt que contiene,

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top