Vai al contenuto
jsonbeautifiers
Italiano

Ordinare JSON

Ordina le chiavi in ordine alfabetico in ogni oggetto annidato, per diff che restano puliti.

Filtra con JSONPath

Sintassi RFC 9535. Il risultato sostituisce il pannello da cui hai aperto questa finestra.

 

Nulla di ciò che incolli lascia il tuo browser. L’allowlist connect-src ne fa una garanzia del browser anziché una promessa. Verificalo tu stesso

Ordina alfabeticamente le chiavi degli oggetti, in modo ricorsivo attraverso ogni oggetto annidato. L’ordine degli array non viene mai toccato, perché l’ordine di un array ha significato e quello delle chiavi di un oggetto no.

Il motivo per farlo sono i diff. Due file con lo stesso contenuto in un ordine di chiavi diverso producono un diff pieno di rumore. Ordinali entrambi e il diff mostra solo ciò che è cambiato davvero.

Quando ordinare è la mossa giusta

Prima di committare un file generato
File di lock, configurazione esportata e qualunque cosa scriva un tool. Se il generatore non garantisce un ordine, ordinare rende il file stabile tra esecuzioni e tra macchine.
Prima di confrontare due documenti
Ordinarli entrambi prima trasforma un diff testuale in qualcosa di leggibile. Il nostro diff strutturale ignora comunque l’ordine delle chiavi, quindi questo serve soprattutto per gli strumenti che non lo ignorano.
Per una forma canonica
Fare l’hash o firmare un documento richiede una serializzazione deterministica. Ordinare le chiavi ne è una parte; la RFC 8785, il JSON Canonicalization Scheme, specifica il resto, compresa la formattazione dei numeri e l’escape delle stringhe.

Quando ordinare è la mossa sbagliata

Un file di configurazione curato a mano in cui l’ordine porta significato per chi legge: le impostazioni importanti in alto, quelle collegate raggruppate. Ordinarlo alfabeticamente è tecnicamente innocuo e praticamente fastidioso.

Qualsiasi caso in cui un consumatore dipenda dall’ordine delle chiavi. Nessuno dovrebbe, ma qualche parser fatto in casa lo fa, e scoprirlo in produzione costa caro.

Come funziona il confronto

Distingue maiuscole e minuscole per impostazione predefinita, il che mette le maiuscole prima delle minuscole perché quello è il loro ordine di code point. Attiva il confronto senza distinzione di maiuscole per ottenere l’ordine che di solito ci si aspetta da un elenco di nomi.

Nota che questo è un ordinamento per code point, non sensibile alla locale. È deterministico ovunque, che è ciò che serve a una forma canonica; un ordinamento sensibile alla locale produrrebbe file diversi su macchine diverse.

How to do this in code

Ordinare le chiavi nel codice.

sh jq

-S vale a ogni livello, non solo a quello superiore.

jq -S . input.json          # sort keys, recursively
jq -S -c . input.json       # sorted and compact
py Python
import json

# sort_keys applies recursively
out = json.dumps(json.loads(text), sort_keys=True, indent=2)
js JavaScript

In JavaScript non esiste uno stringify ordinato integrato, ed è per questo che questo frammento gira così tanto.

// The replacer only receives keys, so sorting needs a walk.
function sortDeep(value) {
  if (Array.isArray(value)) return value.map(sortDeep);
  if (value && typeof value === 'object') {
    return Object.fromEntries(
      Object.keys(value).sort().map((k) => [k, sortDeep(value[k])]),
    );
  }
  return value;
}

const out = JSON.stringify(sortDeep(JSON.parse(text)), null, 2);
go Go

È uno dei rari casi in cui la libreria standard fa la cosa giusta senza che glielo si chieda.

// encoding/json sorts map keys automatically when marshalling
// a map. Struct fields keep their declaration order.
var v map[string]any
json.Unmarshal(data, &v)
out, _ := json.MarshalIndent(v, "", "  ")   // keys sorted

Domande frequenti

Ordinare modifica i miei dati?
Semanticamente no. Gli oggetti JSON non sono ordinati secondo la specifica, quindi un documento ordinato contiene lo stesso valore. Cambia i byte, ed è proprio quello il punto.
Perché gli elementi degli array non vengono ordinati?
Perché l’ordine di un array fa parte dei dati. Trasformare [3,1,2] in [1,2,3] significherebbe cambiare il documento, non riformattarlo.
È la stessa cosa del JSON canonico?
Ne è una parte. La RFC 8785, il JSON Canonicalization Scheme, specifica anche la formattazione dei numeri, l’escape delle stringhe e la normalizzazione Unicode, tutte cose che contano se stai facendo l’hash o firmando il risultato.