Json - merangkai sehingga array berada pada satu baris

Apakah mungkin untuk merangkai objek JSON agar terlihat seperti ini, dengan array dalam satu baris - tidak menjorok ke dalam

{
    "Repeat": {
        "Name": [["Top_level","All"],[[1,1]]],
        "Link": [["Top_level"],[[1,1]]]
    },
    "Delete": ["Confirm","Cancel"],
    "Move": ["Up","Down"],
    "Number": ["Ascending","Descending"]
}

person Chris Glasier    schedule 04.08.2011    source sumber


Jawaban (10)


Coba ini:

var obj = {"Repeat": {"Name":[["Top_level","All"],[[1,1]]],"Link": [["Top_level"],[[1,1]]]},"Delete": ["Confirm","Cancel"],"Move": ["Up","Down"],"Number": ["Ascending","Descending"]};

JSON.stringify(obj,function(k,v){
   if(v instanceof Array)
      return JSON.stringify(v);
   return v;
},2);

Hasil:

"{
  "Repeat": {
    "Name": "[[\"Top_level\",\"All\"],[[1,1]]]",
    "Link": "[[\"Top_level\"],[[1,1]]]"
  },
  "Delete": "[\"Confirm\",\"Cancel\"]",
  "Move": "[\"Up\",\"Down\"]",
  "Number": "[\"Ascending\",\"Descending\"]"
}"
person ericbowden    schedule 26.08.2013
comment
Terima kasih, itu terlihat lebih seperti seharusnya. Saya akan mencobanya pada waktu yang tepat. Apa yang k lakukan? - person Chris Glasier; 28.08.2013
comment
k dan v adalah kunci/nilai untuk objek yang diteruskan ke fungsi itu, dalam hal ini k tidak melakukan apa pun - person ericbowden; 29.08.2013
comment
Array keluar sebagai string tunggal; apakah ada cara yang sama cerdasnya untuk mengembalikannya ke array? Jika demikian, jawaban Anda pasti mendapat tanda centang - person Chris Glasier; 11.11.2013
comment
Hasil cetakannya seperti ini:` gambar: [\2\,\3\,\4\,\5\,\6\,\7\]` - person Chris Glasier; 22.11.2013
comment
Bagian ini menjadi sedikit rumit, yang saya lakukan saat mengimplementasikannya adalah menghapus tanda kutip dan garis miring terbalik dengan regex. Sedangkan untuk array, Anda dapat membuat metode rekursif yang mengulang setiap kali array terdeteksi dan menempelkannya di akhir string keluaran. Ini bisa menjadi sedikit berantakan dari sini. - person ericbowden; 29.11.2013
comment
Regex tampaknya OK tetapi array mungkin berisi string sehingga harus berupa garis miring terbalik, [ dan ] ... akan mencobanya ... semuanya pada waktu yang tepat! - person Chris Glasier; 01.12.2013
comment
Tampaknya menambahkan ini akan menyelesaikan masalah tanda baca:html = html.split('"[').join("["); html = html.split(']"').join("]"); html = html.split('\\"').join('"'); html = html.split('""').join('"'"'"); - person Chris Glasier; 26.09.2014

Jika Anda ingin menampilkan array pendek sebagai satu baris, pertimbangkan untuk menggunakan json-stringify-pretty- kompak. Ini menghasilkan hasil sebagai berikut:

{
  "bool": true,
  "short array": [1, 2, 3],
  "long array": [
    {"x": 1, "y": 2},
    {"x": 2, "y": 1},
    {"x": 1, "y": 1},
    {"x": 2, "y": 2}
  ]
}
person Piotr Migdal    schedule 15.11.2015
comment
Ini bekerja cukup baik setelah Anda menjalankannya. Ini adalah proses yang aneh - atau mungkin saya tidak tahu apa yang saya lakukan... Ini dapat diinstal dengan mudah dengan npm. Setelah itu, agar dapat berfungsi, tag skrip Anda harus menunjuk ke 'index.js' (Tidak ada file js json-stringify-pretty-compact). Kemudian Anda harus mengomentari baris terakhir, seperti ini: //module.exports = stringify. Kemudian Anda bisa menggunakannya sebagai pengganti JSON.stringify, seperti ini: stringify(jSONObject, null, 2). Memang itu membuat JSON terlihat jauh lebih baik. - person Travis Heeter; 04.11.2016

Mengambil jawaban dari ericbowden dan bigp, saya membuat fungsi di bawah ini yang memungkinkan saya mencetak JSON dengan cantik sambil menjaga array pada satu baris dan menjaga array dalam bentuk array alih-alih mengubahnya menjadi string.

function prettyPrintArray(json) {
  if (typeof json === 'string') {
    json = JSON.parse(json);
  }
  output = JSON.stringify(json, function(k,v) {
    if(v instanceof Array)
      return JSON.stringify(v);
    return v;
  }, 2).replace(/\\/g, '')
        .replace(/\"\[/g, '[')
        .replace(/\]\"/g,']')
        .replace(/\"\{/g, '{')
        .replace(/\}\"/g,'}');

  return output;
}
person Alexis Evelyn    schedule 28.02.2019
comment
Terima kasih atas jawaban Anda - ini berfungsi dengan baik. Di sini saya telah menyesuaikan fungsi Anda untuk meneruskan JSLint: const prettyPrintArray = obj => JSON.stringify( obj, (key, val) => (val instanceof Array) ? JSON.stringify(val) : val, 2).replace(/\\/g, '').replace(/\[/g, '[').replace(/\]/g,']').replace(/\{/g, '{').replace(/\}/g,'}'); - person LukeT; 09.06.2020

Pendekatan lain yang saya ambil:

obj => JSON.stringify(obj, (k,v) => Array.isArray(v) ? JSON.stringify(v) : v, 2)
.replace(/"\[[^"\]]*]"/g, r => JSON.stringify(JSON.parse(r)).substr(1).slice(0,-1))

*Array tidak boleh berisi string (perhatikan " di dalam not berisi di dalam regex), jika Anda menghapusnya maka akan menangkap kunci,nilai: "[": "[1,2,3,4]",

Pembaruan 2020-03 - Saya menemukan solusi yang lebih stabil

const obj = {
  "first_name": "John",
  "last_name": "Smith",
  "age": 21,
  "hobbies": [ "programming", "workout", null, undefined, 24, "\"has double quotes\"" ],
  "nested": {
    "arr": [ "one", "two", "three" ],
  },
  "nested_arr": [
    "first as string",
    {
      "latin": [ "alpha", "beta", "[gamma]" ]
    },
    null
  ]
};

const stringify = (obj, indent = 2) => 
  JSON.stringify(obj, (key, value) => {
    if (Array.isArray(value) && !value.some(x => x && typeof x === 'object')) {
      return `\uE000${JSON.stringify(value.map(v => typeof v === 'string' ? v.replace(/"/g, '\uE001') : v))}\uE000`;
    }
    return value;
  }, indent).replace(/"\uE000([^\uE000]+)\uE000"/g, match => match.substr(2, match.length - 4).replace(/\\"/g, '"').replace(/\uE001/g, '\\\"'));

console.log(stringify(obj));

person EliSherer    schedule 14.11.2017
comment
Menurut Anda apakah akan mendapatkan hasil ini: www.glasier.hk - pilih JSON - person Chris Glasier; 15.11.2017
comment
Untuk tujuan umum, saya sarankan menggunakan perpustakaan pihak ketiga seperti yang disarankan oleh @Piotr Migdal - person EliSherer; 15.11.2017

Ingatlah bahwa ini menggunakan lodash untuk mendeteksi Array dan Objek, berikut metode lain yang akan menjaga objek "daun" tetap kompak dalam satu baris:

_.jsonPretty = function(obj, indent) {
    if(!indent) indent = 2;

    return JSON.stringify(obj, function(k,v) {
        //Check if this is a leaf-object with no child Arrays or Objects:
        for(var p in v) {
            if(_.isArray(v[p]) || _.isObject(v[p])) {
                return v;
            }
        }

        return JSON.stringify(v);

        //Cleanup the escaped strings mess the above generated:
    }, indent).replace(/\\/g, '')
        .replace(/\"\[/g, '[')
        .replace(/\]\"/g,']')
        .replace(/\"\{/g, '{')
        .replace(/\}\"/g,'}');
};

Dan gunakan saja seperti ini:

_.jsonPretty(yourObjectToStringify);

Berikut ini contohnya sebelum...

{
  "type": "light-item",
  "name": "Waiting",
  "ringSeqLooping": true,
  "ringSeqHoldLast": false,
  "ringSteps": [
    {
      "type": "light-step",
      "time": 1,
      "audioClipName": "Off",
      "audioVolume": 1,
      "lights": [
        {
          "state": "FadeOn",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        }
      ]
    },
    {
      "type": "light-step",
      "time": "0.5",
      "audioClipName": "Off",
      "audioVolume": 1,
      "lights": [
        {
          "state": "FadeOff",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        }
      ]
    }
  ],
  "stripSeqLooping": true,
  "stripSeqHoldLast": false,
  "stripSteps": [
    {
      "type": "light-step",
      "time": "2",
      "audioClipName": "Off",
      "audioVolume": 1,
      "lights": [
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "FadeOn",
          "color": "#fff"
        },
        {
          "state": "FadeOn",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        }
      ]
    },
    {
      "type": "light-step",
      "time": "2",
      "audioClipName": "Off",
      "audioVolume": 1,
      "lights": [
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "FadeOff",
          "color": "#fff"
        },
        {
          "state": "FadeOff",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        },
        {
          "state": "Off",
          "color": "#fff"
        }
      ]
    }
  ]
}

... dan setelah:

{
  "type": "light-item",
  "name": "Waiting",
  "ringSeqLooping": "true",
  "ringSeqHoldLast": "false",
  "ringSteps": [
    {
      "type": "light-step",
      "time": "1",
      "audioClipName": "Off",
      "audioVolume": "1",
      "lights": [
        {"state":"FadeOn","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"}
      ]
    },
    {
      "type": "light-step",
      "time": "0.5",
      "audioClipName": "Off",
      "audioVolume": "1",
      "lights": [
        {"state":"FadeOff","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"}
      ]
    }
  ],
  "stripSeqLooping": "true",
  "stripSeqHoldLast": "false",
  "stripSteps": [
    {
      "type": "light-step",
      "time": "2",
      "audioClipName": "Off",
      "audioVolume": "1",
      "lights": [
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"FadeOn","color":"#fff"},
        {"state":"FadeOn","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"}
      ]
    },
    {
      "type": "light-step",
      "time": "2",
      "audioClipName": "Off",
      "audioVolume": "1",
      "lights": [
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"FadeOff","color":"#fff"},
        {"state":"FadeOff","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"},
        {"state":"Off","color":"#fff"}
      ]
    }
  ]
}
person bigp    schedule 22.02.2017
comment
Ugh... Saya baru saja melihat beberapa kekurangan (khususnya boolean & angka) di mana ada tanda kutip ganda di sekelilingnya. Saya kira terserah Anda untuk memutuskan apakah aman untuk melakukan lebih banyak penggantian global di seluruh string JSON untuk menghapus kasus Edge tersebut. - person bigp; 22.02.2017

Coba ini:

JSON.stringify(obj,function(k,v){
   if(v instanceof Array)
      return JSON.stringify(v);
   return v;
},4)
.replace(/"\[/g, '[')
.replace(/\]"/g, ']')
.replace(/\\"/g, '"')
.replace(/""/g, '"');
person Maneesh Sharma    schedule 14.09.2017
comment
Saya mencoba tetapi ini tidak berhasil dengan objek multi level - person Chris Glasier; 27.09.2017

Ini adalah versi yang cocok untuk saya. Saya hanya membutuhkannya untuk item tunggal atau array numerik. Namun himpunan boolean true di bawah membuat semua array menjadi satu liner.

Setiap kerangka tampaknya memiliki gotcha-nya sendiri! :)

Saya benar-benar frustrasi sampai saya mengetahui bahwa string.replace hanya berfungsi pada kemunculan pertama. Saya senang sekarang karena saya memiliki solusi!

Beberapa solusi lain sepertinya tidak berhasil untuk saya di node? Tetapi jika solusi yang lebih sederhana berhasil, menurut saya lakukanlah!

const singleLineForNumericAndSingleItemArray = false;
let formatJsonVtStandard = function(key, value) {
    // Edit: Without checking if it is json, strings holding numbers turn to numbers.
    if (typeof(value) === 'string' && (value.startsWith("{") || value.startsWith("["))) {
        try {
            value = JSON.parse(value);
        } catch (ex) {}
    }
    if (!Array.isArray(value)) {
        return value;
    }
    if (value.length === 0) {
        return value;
    }
    if (singleLineForNumericAndSingleItemArray) {
        // Only keep single items and integer arrays on one line
        if (value.length > 1 && value.some(function(v) { return !Number.isInteger(v); })) {
            return value;
        }
    }
    for (var index in value) {
        if (typeof(value[index]) === 'object') {
            return value; // Don't support arrays that contain objects (little too tricky of a shot)
        } else if (typeof(value[index]) === 'string') { // Keep the double quotes
            value[index] = '#¯\_(ツ)_/¯#"#¯\_(ツ)_/¯#' + value[index] + '#¯\_(ツ)_/¯#"#¯\_(ツ)_/¯#';
        }
    }
    return '#¯\_(ツ)_/¯#[#¯\_(ツ)_/¯#' + value.join('#¯\_(ツ)_/¯#,#¯\_(ツ)_/¯# ') + '#¯\_(ツ)_/¯#]#¯\_(ツ)_/¯#';
};

function prettyStringify(json, extraFormatting = null, spacing = 2) {
    const results = JSON.stringify(json, function(key, value) { let result = formatJsonVtStandard(key, value); if (extraFormatting && extraFormatting !== null) { result = extraFormatting(key, result); } return result; }, spacing);
    const results1 = results.split('\"#¯\_(ツ)_/¯#[#¯\_(ツ)_/¯#').join('[');   // string.replace is sidelined: does not replace all occurrences
    const results2 = results1.split('#¯\_(ツ)_/¯#]#¯\_(ツ)_/¯#\"').join(']');  // string.replace is sidelined: does not replace all occurrences
    const results3 = results2.split('#¯\_(ツ)_/¯#\\"#¯\_(ツ)_/¯#').join('\"'); // string.replace is sidelined: does not replace all occurrences
    const results4 = results3.split('#¯\_(ツ)_/¯#,#¯\_(ツ)_/¯#').join(',');    // string.replace is sidelined: does not replace all occurrences
    return results4;
}

Untuk menggunakan ini. Ganti saja JSON.stringify dengan prettyStringify

person TamusJRoyce    schedule 03.05.2019
comment
Ganti #¯\_(ツ)_/¯# dengan ### atau UUID/GUID agar kode lebih mudah dibaca. - person TamusJRoyce; 04.05.2019

Jawaban modern lainnya untuk pertanyaan lama: Lihat FracturedJson. Tautan itu akan membawa Anda ke versi web, tetapi tersedia sebagai aplikasi baris perintah, dan perpustakaan untuk .NET dan JS.

FracturedJson akan menyejajarkan array/objek selama tidak terlalu panjang atau terlalu rumit. Itu juga dapat membagi array menjadi beberapa baris dengan beberapa item per baris.

Berikut ini contoh penggunaan setelan default, namun Anda dapat menyesuaikannya sesuai keinginan terbaik untuk data Anda.

{
    "SimpleItem": 77,
    "ComplexObject": {
        "Subthing1": {"X": 55, "Y": 19, "Z": -4},
        "Subthing2": { "Q": null, "W": [-2, -1, 0, 1] },
        "Distraction": [[], null, null]
    },
    "ShortArray": ["blue", "blue", "orange", "gray"],
    "LongArray": [
        2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 
        79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 
        163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 
        251, 257, 263, 269, 271, 277, 281, 283, 293
    ],
    "LongArray2": [
        [19, 2],
        [3, 8],
        [14, 0],
        [9, 9],
        [9, 9],
        [0, 3],
        [10, 1],
        [9, 1],
        [9, 2],
        [6, 13],
        [18, 5],
        [4, 11],
        [12, 2]
    ]
}

Pengungkapan: Saya penulis FracturedJson. Ini open source di bawah lisensi MIT.

person j-brooke    schedule 08.11.2020
comment
Saya pikir ini adalah solusi terbaik. terima kasih!! - person philo; 14.06.2021

Berikut adalah solusi yang saya kerjakan yang mungkin berguna sebagai dasar untuk melakukan hal serupa:

function labTab(ind){
    var tab,com,a;
    tab = "\t";
    com = [];
    for(a = 0; a < ind; a+=1){
        com.push(tab)
    }
    return com.join("");
}

function nsetEntry(tab,o,obj){
    return tab + '"'+ o + '":' + JSON.stringify(obj[o]);
}

function nsetObject(tab,o,obj,arr,ind){
    var start;
    start = tab + '"'+ o + '":{'; 
    return [start,nsetConstructor(obj[o],arr,ind)].join("\n") + "\n" + tab +"}"; 
}

function nsetConstructor(obj,arr,ind){
    var narr,tab,o,entry;
    narr = [];
    ind += 1;
    tab = labTab(ind);
    for(o in obj){
        if(obj[o].constructor === Object){
            entry = nsetObject(tab,o,obj,arr,ind);
            narr.push(entry); 
        }
        else{
            entry = nsetEntry(tab,o,obj);
            narr.push(entry);
        }
    }
    return narr.join(",\n");
}

function nsetLevels(obj,arr,ind){
    var o,start,tab;
    tab = labTab(ind);
    for(o in obj){
        if(obj[o].constructor === Object){
            entry = nsetObject(tab,o,obj,arr,ind);
            arr.push(entry); 
        }
        else{
            entry = nsetEntry(tab,o,obj);   
            arr.push(entry);
        }
    }
        return arr.join(",\n");
}

function nsetSave(){
    var json,o,ind,tab,obj,start,head,tail;
    json = [];
    for(o in nset){
        ind = 1;
        tab = labTab(ind);
        start = tab + '"'+ o + '":{';
        ind = 2;
        tab = labTab(ind);
        obj = nset[o];
        json.push([start,nsetLevels(obj,[],ind)].join("\n"))
    }
    head = "{\n";
    tail = "\n\t}\n}"
    FW.Write([head,json.join("\n\t},\n"),tail].join(""),"xset.json")
}

Saya tidak tahu cara melakukan penggantian karena beberapa anggota turun lima level, jadi saya membuat ulang semuanya. Solusinya tidak terlalu bagus tetapi saya mendapatkan apa yang ingin saya capai - contoh di bawah:

    "Key":{
        "Label":{
            "Change":["Input"],
            "Repeat":{
                "Name":[["Top_level","All"],[[1,1]]],
                "Link":[["Top_level"],[[1,1]]]
            },
            "Delete":["Confirm","Cancel"],
            "Move":["Up","Down"],
            "Number":["Ascending","Descending"]
        },
        "Class":{
            "Change":["Input"]
        },
person Chris Glasier    schedule 10.08.2011

Saya menggunakan format JSON untuk file konfigurasi aplikasi saya. Keduanya cukup berbeda dan cukup besar, sehingga diperlukan aturan pemformatan yang berbeda agar terlihat lebih baik dan mudah dibaca. Sayangnya, jawaban yang diberikan tidak cukup fleksibel sehingga saya membuat implementasi sendiri yang disebut perfect-json untuk mempercantik JSON.

Anggaplah Anda ingin memformat objek dalam pertanyaan seperti ini:

{
  "Repeat": {
    "Name": [
      ["Top_level", "All"],
      [[1, 1]]
    ],
    "Link": [
      ["Top_level"],
      [[1, 1]]
    ]
  },
  "Delete": ["Confirm", "Cancel"],
  "Move": ["Up", "Down"],
  "Number": [
    "Ascending",
    "Descending"
  ]
}

Dengan perfect-json dapat dicapai:

import perfectJson from 'perfect-json';

const obj = {
  Repeat: {
    Name: [['Top_level', 'All'], [[1, 1]]],
    Link: [['Top_level'], [[1, 1]]]
  },
  Delete: ['Confirm', 'Cancel'],
  Move: ['Up', 'Down'],
  Number: ['Ascending', 'Descending']
};

console.log(perfectJson(obj, {
  singleLine: ({ key, path, depth }) => {
    if (['Delete', 'Move'].includes(key)) {
      return true;
    }
    if (depth >= 3 && ['Name', 'Link'].includes(path[1])) {
      return true;
    }
    return false;
  }
}));

Juga mudah untuk menempatkan setiap array pada satu baris seperti yang ditanyakan dalam pertanyaan:

console.log(perfectJson(obj, {
  indent: 4,
  singleLine: ({ value }) => Array.isArray(value)
}));
person ezze    schedule 27.07.2021
comment
Tepat pada peringatan sepuluh tahun pertanyaan itu. Beri aku waktu untuk menyerapnya; Saya yakin ini layak mendapat suara positif. - person Chris Glasier; 27.07.2021