メニュー
検索
言語
タグ
JSON文字列またはオブジェクトを整形して文字列にする関数 (formatJSON)
総合評価: - 作成日: 2025-11-15
コメント:
Braveブラウザで動作確認済み。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>formatJSON</title>
<script>
/**
* JSON文字列またはオブジェクトを整形して文字列にする。
*
* json ... JSON文字列またはオブジェクト
* indent ... 半角スペースの数、または文字列
* sort ... 'asc'で昇順ソート、'desc'で降順ソート
*
* 返り値 ... 整形した文字列
*/
function formatJSON (json, {
indent=4, // 2 | 4 | '\t' | etc
sort=null, // 'asc' | 'desc'
}={}) {
if (typeof json === 'string') {
json = JSON.parse(json)
}
let dst = {
text: '',
}
function _wrap (o) {
let s = '"'
let os = '' + o
for (let i = 0; i < os.length; i++) {
if (os[i] === '"') {
s += '\\'
}
s += os[i]
}
s += '"'
return s
}
function _indent () {
let s = ''
if (typeof indent === 'string') {
s += indent
} else if (typeof indent === 'number') {
for (let i = 0; i < indent; i++) {
s += ' '
}
}
return s
}
function _pad (o, dep, ind=true) {
if (!ind) {
return '' + o
}
let s = ''
for (let i = 0; i < dep; i++) {
s += _indent()
}
s += '' + o
return s
}
function _sort (o) {
if (sort === 'asc') {
o.sort()
} else if (sort === 'desc') {
o.sort((a, b) => {
if (typeof a === 'string' &&
typeof b === 'string') {
return b.localeCompare(a)
} else {
return b - a
}
})
}
}
function _re (dst, o, dep, ind=true) {
if (typeof o === 'number' ||
typeof o === 'boolean') {
dst.text += _pad(o, dep, ind)
return
} else if (typeof o === 'string') {
dst.text += _pad(_wrap(o), dep, ind)
} else if (Array.isArray(o)) {
_sort(o)
dst.text += _pad('[\n', dep, ind)
for (let i = 0; i < o.length-1; i++) {
_re(dst, o[i], dep+1)
dst.text += ',\n'
}
if (o.length) {
_re(dst, o[o.length-1], dep+1)
dst.text += '\n'
}
dst.text += _pad(']', dep)
} else if (typeof o === 'object') {
dst.text += _pad('{\n', dep, ind)
let keys = Object.keys(o)
_sort(keys)
for (let i = 0; i < keys.length-1; i++) {
let k = keys[i]
dst.text += _pad(k + ': ', dep+1)
_re(dst, o[k], dep+1, false)
dst.text += ',\n'
}
if (keys.length) {
let k = keys[keys.length-1]
dst.text += _pad(k + ': ', dep+1)
_re(dst, o[k], dep+1, false)
dst.text += '\n'
}
dst.text += _pad('}', dep)
}
}
_re(dst, json, 0)
return dst.text
}
document.addEventListener('DOMContentLoaded', () => {
let o
let s
let output = document.getElementById('output')
o = {
aa: 111,
bb: 'bbb',
cc: [
'abc',
[223, 123, 323],
{
ccaa: 'ccaa',
ccbb: [223, 123, 323],
}
],
dd: {
ee: 'ee',
gg: [223, 123, 323],
ff: {
ii: 'ii',
hh: 123,
}
}
}
s = formatJSON([
123, 223, 3.14,
{ aa: 'a"a"a', bb: 'bb' },
])
output.textContent += s
console.assert(s === `[
123,
223,
3.14,
{
aa: "a\\"a\\"a",
bb: "bb"
}
]`)
s = formatJSON(o, {
indent: '\t',
})
output.textContent += s
console.assert(s === `{
\taa: 111,
\tbb: "bbb",
\tcc: [
\t\t"abc",
\t\t[
\t\t\t223,
\t\t\t123,
\t\t\t323
\t\t],
\t\t{
\t\t\tccaa: "ccaa",
\t\t\tccbb: [
\t\t\t\t223,
\t\t\t\t123,
\t\t\t\t323
\t\t\t]
\t\t}
\t],
\tdd: {
\t\tee: "ee",
\t\tgg: [
\t\t\t223,
\t\t\t123,
\t\t\t323
\t\t],
\t\tff: {
\t\t\tii: "ii",
\t\t\thh: 123
\t\t}
\t}
}`)
s = formatJSON(o)
output.textContent += s
console.assert(s === `{
aa: 111,
bb: "bbb",
cc: [
"abc",
[
223,
123,
323
],
{
ccaa: "ccaa",
ccbb: [
223,
123,
323
]
}
],
dd: {
ee: "ee",
gg: [
223,
123,
323
],
ff: {
ii: "ii",
hh: 123
}
}
}`)
s = formatJSON(o, {
sort: 'asc',
})
output.textContent += s
console.assert(s === `{
aa: 111,
bb: "bbb",
cc: [
[
123,
223,
323
],
{
ccaa: "ccaa",
ccbb: [
123,
223,
323
]
},
"abc"
],
dd: {
ee: "ee",
ff: {
hh: 123,
ii: "ii"
},
gg: [
123,
223,
323
]
}
}`)
s = formatJSON(o, {
sort: 'desc',
})
output.textContent += s
console.assert(s === `{
dd: {
gg: [
323,
223,
123
],
ff: {
ii: "ii",
hh: 123
},
ee: "ee"
},
cc: [
[
323,
223,
123
],
{
ccbb: [
323,
223,
123
],
ccaa: "ccaa"
},
"abc"
],
bb: "bbb",
aa: 111
}`)
})
</script>
</head>
<body>
<pre><code id="output"></code></pre>
</body>
</html>