Pergunta

Ao gerar manualmente um objeto JSON ou matriz, muitas vezes é mais fácil deixar uma vírgula à direita no último item do objeto ou array. Por exemplo, o código para a saída de uma matriz de seqüências pode parecer (em C ++ como pseudocódigo):

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

dando-lhe uma string como

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

Isso é permitido?

Foi útil?

Solução

a especificação JSON não permite uma vírgula à direita. Há alguns navegadores que lhe permitam, mas geralmente você precisa se preocupar com todos os navegadores.

Em geral eu tento contornar o problema, e adicionar a vírgula antes do valor real, de modo que você acabar com código que se parece com isso:

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("]");

Essa linha um extra de código em seu loop for é pouco caro ...

Outra alternativa que usei quando a saída de uma estrutura de JSON de um dicionário de alguma forma é sempre acrescentar uma vírgula após cada entrada (como você está fazendo acima) e, em seguida, adicionar uma entrada fictícia no final que não tenha arrastando vírgula (mas isso é apenas preguiçoso; ->).

não funciona bem com uma variedade infelizmente.

Outras dicas

No. O JSON especificação, como mantida a http://json.org , não permite direita vírgulas. Pelo que tenho visto, alguns parsers silenciosamente pode permitir-lhes ao ler uma string JSON, enquanto outros vão jogar erros. Para interoperabilidade, você não deve incluí-lo.

O código acima poderia ser reestruturada, seja para remover a vírgula à direita ao adicionar o terminador array ou para adicionar a vírgula antes de itens, ignorando que, para o primeiro.

Simples, barato, fácil de ler, e sempre funciona independentemente das especificações.

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

A atribuição redundante $ delim é um pequeno preço a pagar. Também funciona tão bem se não houver laço explícita, mas fragmentos de código separadas.

vírgulas extras são permitidos em JavaScript, mas não funcionam no IE. Douglas Crockford de versionless JSON especificação não permitir que eles, e porque era versionless isso não era para a mudança. A especificação ES5 JSON permitiu-lhes como uma extensão, mas de Crockford RFC 4627 não, e ES5 revertido para não permitir-lhes. Firefox seguiram o exemplo. Internet Explorer é por isso que nós não podemos ter coisas agradáveis.

Como é já foi dito, JSON especificação (com base no ECMAScript 3) não permite vírgula à direita. ES> = 5 permite isso, então você pode realmente usar essa notação em JS puros. Tem sido discutido sobre, e alguns analisadores se apoiá-lo ( http: // bolinfest. com / ensaios / json.html , http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/ ), mas é o fato de especificação (como mostrado em < a href = "http://json.org/" rel = "noreferrer"> http://json.org/ ) que não deve trabalho em JSON. Aquela coisa disse ...

... Eu estou perguntando por que ninguém apontou que você pode realmente dividir o laço na iteração e uso 0 líder vírgula em vez de arrastando um para se livrar do cheiro de código de comparação e qualquer sobrecarga de desempenho real no circuito, resultando em um código que é realmente mais curto, mais simples e mais rápido (devido a nenhuma ramificação / condicionais no circuito) do que outras soluções propostas.

por exemplo. (Em um pseudocódigo C-estilo semelhante ao código proposto pelo 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("]");

codificadores de PHP pode querer verificar implode () . Isso leva uma série junta-lo usando uma corda.

A partir da docs ...

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

Curiosamente, ambos C & C ++ (e eu acho que C #, mas eu não tenho certeza) especificamente permitir que a vírgula à direita - para exatamente a razão dada: Faz programmaticly geração de listas muito mais fácil. Não sei por que JavaScript não siga o seu exemplo.

Use JSON5. Não use JSON.

  • Objetos e matrizes podem ter à direita vírgulas
  • chaves de objeto pode ser não cotadas se eles são identificadores válidos
  • Cordas pode ser
  • single-citado
  • Cordas pode ser dividida em várias linhas
  • Os números podem ser hexadecimal (base 16)
  • Os números podem começar ou terminar com um ponto decimal (esquerda ou à direita).
  • Os números podem incluir Infinito e -Infinity.
  • Os números podem começar com um sinal explícito de mais (+).
  • Ambos inline (single-line) e bloco (multi-linha) Comentários são permitidos.

http://json5.org/

https://github.com/aseemk/json5

De acordo com a Classe JSONArray especificação :

  • Um extra, (vírgula) pode aparecer logo antes do colchete de fechamento.
  • O valor nulo será inserido quando há, (vírgula) elisão.

Então, como eu o entendo, deve ser permitido escrever:

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

Mas pode acontecer que alguns analisadores voltará a 7, como contagem de itens (como IE8 como Daniel Earwicker apontou) em vez do esperado 6.


Editado:

Eu encontrei este JSON Validador que valida um JSON corda contra RFC 4627 (o tipo de mídia application / json para JavaScript Object Notation) e contra a especificação da linguagem JavaScript. Realmente aqui uma matriz com uma vírgula à direita é considerado válido apenas para JavaScript e não para a especificação RFC 4627.

No entanto, na RFC 4627 especificação afirma-se que:

2.3. Arrays

Uma estrutura de matriz é representada como colchetes torno de zero ou mais valores (ou elementos). Os elementos são separados por vírgulas.

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

Para mim, este é novamente um problema de interpretação. Se você escrever que Os elementos são separados por vírgulas (sem indicar algo sobre casos especiais, como o último elemento), que poderia ser entendido em ambos os sentidos.

P.S. RFC 4627 não é um padrão (como explicitamente indicado), e já está obsolited pela RFC 7159 (que é um projecto padrão) RFC 7159

De minha experiência, eu descobri que diferentes navegadores lidar com à direita vírgulas em JSON de forma diferente.

Ambos Firefox e Chrome lida com isso muito bem. Mas IE (todas as versões) parece quebrar. Quero dizer realmente quebrar e parar de ler o resto do script.

Tendo isso em mente, e também o fato de que é sempre bom para escrever código compatível, sugiro gastar o esforço extra de certificar-se que não há nenhuma vírgula à direita.

:)

Eu mantenho uma contagem atual e compará-lo com uma contagem total. Se a contagem atual é menor do que a contagem total, eu exibir a vírgula.

pode não funcionar se você não tem uma contagem total antes de executar a geração JSON.

Então, novamente, se o seu usando PHP 5.2.0 ou melhor, você pode simplesmente formatar sua resposta usando a API JSON construído em.

Com JSON Descontraído, você pode ter à direita vírgulas, ou simplesmente deixar as vírgulas fora . Eles são opcionais.

Não há nenhuma razão em todas as vírgulas precisam estar presentes para analisar uma JSON-like documento.

Dê uma olhada na especificação JSON Descontraído e você vai ver como 'barulhento' a especificação JSON original está. Way demasiadas vírgulas e aspas ...

http://www.relaxedjson.org

Você também pode experimentar o seu exemplo usando este analisador RJSON on-line e vê-lo se analisados ??corretamente.

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

Eu costumo loop sobre a matriz e anexar uma vírgula após cada entrada na string. Após o ciclo I apagar a última vírgula novamente.

Talvez não a melhor maneira, mas menos caro do que verificar cada vez que se é o último objeto no loop eu acho.

Não é recomendado, mas você ainda pode fazer algo assim para analisá-lo.

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

Há uma maneira possível para evitar uma se-ramo no circuito.

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

Uma vez que uma for-loop é utilizada para repetir uma matriz, ou estrutura de dados iteráveis ??semelhante, pode-se utilizar o comprimento da matriz, como mostrado,

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

Com datafile.txt contendo,

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top