Comparador de JSON online

O comparador de JSON compara o conteúdo de dois JSONs e lista o que foi adicionado, removido ou alterado, com o caminho de cada diferença, como $.usuario.idade. A ordem das chaves e a formatação são ignoradas, então só aparecem mudanças de verdade. A comparação é feita no seu navegador, sem enviar os dados a nenhum servidor.

Atualizado em · Por Leonardo Gaertner

    Achou um resultado errado ou tem uma sugestão? Avise por e-mail.

    Como usar

    1. Cole o JSON original à esquerda e o JSON modificado à direita.
    2. Veja a lista de diferenças, cada uma com o caminho e o valor antes e depois.
    3. Use Trocar os lados para inverter a comparação e Copiar diferenças para levar o relatório.

    Como funciona

    A ferramenta lê os dois JSONs e os compara valor a valor. Em objetos, cada chave é comparada com a mesma chave do outro lado, sem importar a ordem. Chaves que só existem em um lado aparecem como adicionadas ou removidas, e valores diferentes aparecem como alterados.

    Listas são comparadas pela posição: o item 0 com o item 0, o item 1 com o item 1, e assim por diante. Por isso, inserir um item no começo de uma lista faz os itens seguintes aparecerem como alterados. Se a ordem dos itens não importa para você, ordene as listas antes de comparar.

    Números são comparados pelo valor (1 e 1.0 são iguais), e valores de tipos diferentes, como o texto "1" e o número 1, contam como alterados. Inteiros acima de 9.007.199.254.740.991 perdem precisão ao serem lidos e podem parecer iguais mesmo sendo diferentes, e a ferramenta avisa quando encontra um número assim.

    Exemplo

    Original: {"nome":"Ana","idade":30,"end":{"rua":"A"}}

    Modificado: {"end":{"rua":"B"},"nome":"Ana","idade":31,"ativo":true}

    alterado $.idade: 30 → 31

    alterado $.end.rua: "A" → "B"

    adicionado $.ativo: true

    Fonte: RFC 8259: o formato JSON; RFC 6902: JSON Patch

    Em código

    Para comparar dois JSON em código, compare os dados e não o texto: a ordem das chaves não conta, a das listas conta, e os tipos precisam bater.

    JavaScript
    // Lista as diferenças entre dois valores JSON já lidos com JSON.parse.
    // A ordem das chaves não conta; as listas são comparadas posição a posição.
    function diffJSON(a, b, caminho = '$', saida = []) {
      const ehObjeto = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
      if (ehObjeto(a) && ehObjeto(b)) {
        for (const k of new Set([...Object.keys(a), ...Object.keys(b)])) {
          const p = `${caminho}.${k}`;
          // Object.hasOwn, e não "k in b": com in, uma chave toString existiria em todo objeto
          if (!Object.hasOwn(b, k)) saida.push({ caminho: p, tipo: 'removido', antes: a[k] });
          else if (!Object.hasOwn(a, k)) saida.push({ caminho: p, tipo: 'adicionado', depois: b[k] });
          else diffJSON(a[k], b[k], p, saida);
        }
      } else if (Array.isArray(a) && Array.isArray(b)) {
        for (let i = 0; i < Math.max(a.length, b.length); i++) {
          const p = `${caminho}[${i}]`;
          if (i >= b.length) saida.push({ caminho: p, tipo: 'removido', antes: a[i] });
          else if (i >= a.length) saida.push({ caminho: p, tipo: 'adicionado', depois: b[i] });
          else diffJSON(a[i], b[i], p, saida);
        }
      } else if (a !== b) {
        saida.push({ caminho, tipo: 'alterado', antes: a, depois: b });
      }
      return saida;
    }
    Python
    def _iguais(a, b) -> bool:
        # No Python, True == 1. No JSON, true e 1 são valores diferentes
        if isinstance(a, bool) or isinstance(b, bool):
            return type(a) is type(b) and a == b
        return a == b
    
    
    def diff_json(a, b, caminho: str = "$", saida: list | None = None) -> list:
        """Diferenças entre dois valores lidos com json.loads (ordem das chaves não conta)."""
        saida = [] if saida is None else saida
        if isinstance(a, dict) and isinstance(b, dict):
            for k in list(a) + [k for k in b if k not in a]:
                p = f"{caminho}.{k}"
                if k not in b:
                    saida.append({"caminho": p, "tipo": "removido", "antes": a[k]})
                elif k not in a:
                    saida.append({"caminho": p, "tipo": "adicionado", "depois": b[k]})
                else:
                    diff_json(a[k], b[k], p, saida)
        elif isinstance(a, list) and isinstance(b, list):
            for i in range(max(len(a), len(b))):
                p = f"{caminho}[{i}]"
                if i >= len(b):
                    saida.append({"caminho": p, "tipo": "removido", "antes": a[i]})
                elif i >= len(a):
                    saida.append({"caminho": p, "tipo": "adicionado", "depois": b[i]})
                else:
                    diff_json(a[i], b[i], p, saida)
        elif not _iguais(a, b):
            saida.append({"caminho": caminho, "tipo": "alterado", "antes": a, "depois": b})
        return saida

    Trata true e 1 como diferentes, como o JSON.

    PHP
    <?php
    // Compara dois JSON pelo conteúdo, ignorando a ordem das chaves dos objetos
    function jsonIguais(string $a, string $b): bool
    {
        $ordenar = function ($v) use (&$ordenar) {
            if (!is_array($v)) {
                return $v;
            }
            $v = array_map($ordenar, $v);
            if (!array_is_list($v)) {
                ksort($v, SORT_STRING); // objeto: ordena as chaves; lista: mantém a ordem
            }
            return $v;
        };
        $va = $ordenar(json_decode($a, true, 512, JSON_THROW_ON_ERROR));
        $vb = $ordenar(json_decode($b, true, 512, JSON_THROW_ON_ERROR));
        return $va === $vb; // === e não ==: com ==, "1" seria igual a 1
    }

    Perguntas frequentes

    A ordem das chaves faz diferença na comparação?

    Não. Em um objeto JSON a ordem das chaves não tem significado, então dois objetos com as mesmas chaves e valores em ordens diferentes são considerados iguais.

    E se os itens de uma lista estiverem em outra ordem?

    Eles são comparados pela posição, então uma lista em outra ordem aparece com diferenças. Se a ordem não importa no seu caso, ordene as listas dos dois lados antes de comparar.

    Qual a diferença entre este comparador e o diff de texto?

    O diff de texto compara linhas e caracteres e enxerga qualquer mudança de formatação. O comparador de JSON compara o conteúdo: ignora espaços, quebras de linha e a ordem das chaves, e mostra o caminho de cada valor que mudou.

    O resultado é um JSON Patch?

    Não. O relatório é feito para leitura humana. O JSON Patch (RFC 6902) é um formato para aplicar mudanças por programa e tem regras próprias, que esta ferramenta não gera.