Làm cách nào để kiểm tra JSON.stringify () một phần?

Oct 01 2020

Người dùng có thể tải xuống các tệp JSON từ ứng dụng của chúng tôi, mà tôi muốn xác minh trước để gỡ lỗi dễ dàng hơn nếu tất cả nằm trong một dòng. Tuy nhiên, điều này làm tăng kích thước tệp lên gần 40% ngay cả khi thụt lề chỉ là một tab hoặc khoảng trắng.

Như một sự thỏa hiệp, tôi muốn loại trừ tất cả các giá trị có ví dụ như khóa "lớn" khỏi quá trình kiểm tra trước, như sau:

{
 "small":
 {
  "a": 1,
  "b": 2,
  "large": {"a":1,"b":2,"c":3,"d":"the \"large\" object should not be prettified"} 
 },
  "large": {"a":1,"b":2,"c":3,"d":"the \"large\" object should not be prettified"}
}

Tôi đã cố gắng giải quyết vấn đề này bằng cách sử dụng tham số thay thế của JSON.stringify:

JSON.stringify(data,(key,value)=>key==="large"?JSON.stringify(data):value,'\t');

Tuy nhiên, các giá trị cho các khóa "lớn" kết thúc bằng cách thoát:

data = 
{
     "small":
     {
      "a": 1,
      "b": [2,3,4,5],
      "large": {"myarray":[1,2,3,4],"b":2,"c":3,"d":"the \"large\" object should not be prettified"} 
     },
      "large": {"a":1,"b":2,"c":3,"d":"the \"large\" object should not be prettified"}
    }
    
 const json =  JSON.stringify(data,(key,value)=>key==="large"?JSON.stringify(data):value,'\t');
 document.getElementById("json").innerText = json;
<html>
<body>
<pre id="json">
</pre>
</body>
</html>

Làm cách nào tôi có thể ngăn việc thoát này xảy ra hoặc nếu không thì bảo đảm một phần cho JSON trong JavaScript?

Trả lời

2 sbgib Oct 06 2020 at 16:00

Mỗi khi bạn gọi JSON.stringifymột đối tượng (hoặc một phần của đối tượng) nhiều hơn một lần , bạn sẽ gặp phải các dấu thanh thoát. Trong trường hợp này, sau khi JSON.stringifyhàm bên trong đã được áp dụng bên trong hàm thay thế, không có cách nào để nói với JSON.stringifyhàm bên ngoài không xử lý cá thể đó như bất kỳ chuỗi nào khác.

Vì vậy, tôi nghĩ nếu mục tiêu của bạn là xâu chuỗi 'một phần' một đối tượng, bạn cần phải viết một hàm thực hiện điều đó. Đối với vấn đề này, tôi sẽ đề xuất một cái gì đó như thế này:

data = {
  "small": {
    "a": 1,
    "b": [2, 3, 4, 5],
    "c": [2, {"test":"example"}, [4,4], 5],
    "large": {
      "myarray": [1, 2, 3, 4],
      "b": 2,
      "c": 3,
      "d": "the \"large\" object should not be prettified"
    }
  },
  "large": {
    "a": 1,
    "b": 2,
    "c": 3,
    "d": "the \"large\" object should not be prettified"
  }
}

function print(obj, exclude, space) {
  let recur = (obj, spacing, inarray) => {
    let txt = '';

    if (inarray) {
      if (Array.isArray(obj)) {        
        txt += '[';

        for(let i=0;i<obj.length;i++) {
          txt += recur(obj[i], spacing + space, true);
        };

        txt = txt.substr(0, Math.max(1,txt.length - 2)) + ']';
        
      } else if (typeof obj === 'object' && obj !== null) {
        txt += '{' + recur(obj, spacing + space, false) + '\n' + spacing + '}';
      } else if (typeof obj === 'string') {
        txt += obj.replaceAll(/\"/g, '\\"') + '"';
      } else {
        txt += obj;
      };
      
      return txt + ', ';
      
    } else {
      for (let key of Object.keys(obj)) {
        if (exclude.indexOf(key) !== -1) {
          txt += '\n' + spacing + '"' + key + '": ' + JSON.stringify(obj[key]);
        } else if (Array.isArray(obj[key])) {
          txt += '\n' + spacing + '"' + key + '": [';
          
          for(let i=0;i<obj[key].length;i++) {
            txt += recur(obj[key][i], spacing + space, true);
          };
          
          txt = txt.substr(0, Math.max(1,txt.length - 2)) + ']';
          
        } else if (typeof obj[key] === 'object' && obj[key] !== null) {
          txt += '\n' + spacing + '"' + key + '": {' + recur(obj[key], spacing + space, false) + '\n' + spacing + '}';
        } else if (typeof obj[key] === 'string') {
          txt += '\n' + spacing + '"' + key + '": "' + obj[key].replaceAll(/\"/g, '\\"') + '"';
        } else {
          txt += '\n' + spacing + '"' + key + '": ' + obj[key];
        };
        
        txt += ',';
      };
      
      return txt.substr(0, txt.length - 1);
    };

  };
  return (Array.isArray(obj) ? '[' + recur(obj, space, true) + '\n' + ']' : '{' + recur(obj, space, false) + '\n' + '}');
};

document.getElementById("json").innerText = print(data, ['large'], '\t');
<html>
<body>
  <pre id="json">
</pre>
</body>
</html>

Ở đây, một hàm đệ quy được sử dụng, sẽ lặp qua các khóa của một đối tượng và nối cặp khóa-giá trị vào một chuỗi, xử lý các kiểu dữ liệu khác nhau. Nếu keytìm thấy trong excludemảng, thì nó được xâu chuỗi.

Bằng cách lặp lại các phím và áp dụng có điều kiện JSON.stringifykhi cần thiết, bạn đang tránh được vấn đề trên một cách hiệu quả.

Tôi chắc rằng có thể có những trường hợp phức tạp cần lưu ý khi tự viết JSON thay vì sử dụng một hàm tích hợp, nhưng bạn có thể điều chỉnh một cái gì đó như thế này cho phù hợp với nhu cầu cụ thể của mình.

EDIT: câu trả lời được cập nhật để xem xét tốt hơn các mảng bên trong đối tượng.