LoginSignup
2
0

More than 5 years have passed since last update.

JSON.stringifyの追加引数とソート

Posted at

昨日行き詰まっていたところでどうしようか考えて、結局はjkr2255/sorted-json-stringifyなんてものを作ってしまいました。

オブジェクトの管理に依存せず並べ替える

突然ですが、JSON.stringify({'30': 'a', '5': 'b'})はどうなると思いますか?多くのブラウザでは、'{"5":"b","30":"a"}'という結果となります。実際、他の値を入れてみた感触でも、数値キーに関しては別枠でハンドリングしているような、妙な挙動を示しました。

実際にこのようなブラックボックスに遭遇してしまった以上、デフォルトのJSON.stringifyでは、順番がどうなるかなんてわかりません。とはいえ、JSON.stringify全部を再実装するのも面倒だし、出来上がったJSONのパースも色々考えると複雑そうだし…みたいなことを考えていました。

JSON.stringifyの仕様を見ていて

そんな中でMDNを見ていると、JSON.stringifyには3つの引数があると書いてありました。

  • replacer…ルールに従ってオブジェクトを置き換える
  • space…見栄えをよくするために、JSONにスペースを挿入する

つまり、spaceでインデントをかけた上で、そのインデントを数える、という手法を取れば、改めて大掛かりにパースしなくてもJSONの入れ子構造を抽出できるということがわかりました。

実際に作ってみた

ということで、

  1. space = 1で、デフォルトのJSON.stringifyを使って、改行&インデントありのJSONを生成する
  2. 行ごとに区切って、インデントのスペースの数を数えておく
  3. インデント位置で構造を把握しつつ、JSONを並べ替えていく
  4. 最後にインデントなどを調整して、最終型のJSONを作る

このような流れで実装することができました。なお、ハマった箇所としては、space=0のときは"foo":"bar"のようにキーと値が密着するのに対して、spaceが入る場合には"foo": "bar"とスペースが1つ入る、となっていて、そこの差で一度コケました。

なお、今回これを作るのにあたって、Mocha、Chai、Rollupと言ったライブラリをはじめて使ってみました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0