Все статьи

JSON Sort Keys: зачем сортировать ключи объекта

Спецификация JSON формально не определяет порядок ключей в объекте — {"a": 1, "b": 2} и {"b": 2, "a": 1} являются одинаковыми данными. Но на практике порядок ключей всё равно часто имеет значение для людей и инструментов, работающих с этими данными.

Зачем сортировать ключи

  • Сравнение (diff). Если два JSON-документа с одинаковыми данными имеют разный порядок ключей, текстовый diff покажет ложную разницу. Сортировка устраняет эту проблему.
  • Детерминированный вывод. Если один и тот же объект сериализуется несколько раз (например, для генерации хеша или кеш-ключа), отсортированные ключи гарантируют одинаковый результат каждый раз.
  • Читаемость. Отсортированный по алфавиту объект легче быстро просмотреть и найти нужное поле, особенно в больших структурах.

Рекурсивная сортировка

Чтобы результат был предсказуемым, сортировку обычно применяют рекурсивно — не только к ключам верхнего уровня, но и к ключам всех вложенных объектов на любой глубине. Порядок элементов в массивах при этом не меняется, поскольку для массивов порядок элементов является значимой частью данных.

Когда это не нужно

Если JSON потребляет только программа (а не человек или diff-инструмент), сортировка ключей обычно не даёт никакого практического преимущества — парсеры читают объект одинаково независимо от порядка полей.

Почему побайтовая сортировка кириллицы обычно «просто работает»

Кириллический блок в Unicode устроен так, что буквы от а до я идут подряд возрастающими кодпоинтами в том же порядке, что и в русском алфавите — поэтому наивная побайтовая (кодпоинт за кодпоинтом) сортировка ключей вида "апельсин", "банан", "вишня" почти всегда совпадает с привычным алфавитным порядком. Единственная типичная неожиданность — это то, что заглавные буквы (А-Я, коды 0x0410–0x042F) идут в таблице Unicode раньше строчных (а-я, коды 0x0430–0x044F), поэтому ключ "Банан" при побайтовом сравнении окажется раньше "апельсин", хотя по смыслу алфавита должно быть наоборот.

Сортировка и локаль

Алфавитная сортировка ключей, содержащих не только латиницу, зависит от того, сравниваются символы побайтово (Unicode code point) или с учётом языковых правил (locale-aware collation). Например, побайтовое сравнение ставит заглавные буквы перед строчными независимо от алфавита, тогда как сортировка с учётом локали может упорядочить ключи иначе — это стоит учитывать, если результат сравнивают между разными языками или системами.

Попробовать инструмент