JSON กำหนดชุด


110

JSON.stringify () ชุดหนึ่งจะเป็นอย่างไร

สิ่งที่ใช้ไม่ได้ใน Chromium 43:

var s = new Set(['foo', 'bar']);

JSON.stringify(s); // -> "{}"
JSON.stringify(s.values()); // -> "{}"
JSON.stringify(s.keys()); // -> "{}"

ฉันคาดหวังว่าจะได้สิ่งที่คล้ายกับอาร์เรย์แบบอนุกรม

JSON.stringify(["foo", "bar"]); // -> "["foo","bar"]"

คำตอบ:


117

JSON.stringify ใช้ไม่ได้โดยตรงกับชุดเนื่องจากข้อมูลที่จัดเก็บในชุดไม่ได้ถูกจัดเก็บเป็นคุณสมบัติ

แต่คุณสามารถแปลงชุดเป็นอาร์เรย์ จากนั้นคุณจะสามารถสตริงได้อย่างถูกต้อง

สิ่งต่อไปนี้จะทำเคล็ดลับ:

JSON.stringify([...s]);
JSON.stringify([...s.keys()]);
JSON.stringify([...s.values()]);
JSON.stringify(Array.from(s));
JSON.stringify(Array.from(s.keys()));
JSON.stringify(Array.from(s.values()));

2
Array.from()ผมก็จะนำเสนอ แต่นี่ดูดีกว่าในเชิงสำนวน
TaoPR

4
เพื่อเพิ่มข้อมูลอ้างอิงMDNมีตัวอย่างบางส่วนของสิ่งนี้และเทคนิคอื่น ๆ ที่เกี่ยวข้อง
Amit

5
ความเข้าใจในรายการสามารถใช้งานได้เช่นกัน:JSON.stringify([_ for (_ of s)])
Whymarrh

1
วิธีการที่ยอดเยี่ยมทั้งหมดน่าเสียดายที่พวกเขาไม่ทำงานใน Chromium 43 นอกกรอบเนื่องจากการแพร่กระจายและ Array.from ยังไม่ได้ใช้งาน ดูเหมือนบาเบลจะช่วยชีวิต
MitMaro

2
ข้อเสนอปัจจุบันเพื่อปรับปรุงค่าเริ่มต้นของSet.prototype.toJSON: github.com/DavidBruant/Map-Set.prototype.toJSON
Oncle Tom

35

ใช้สิ่งนี้ JSON.stringify :

(เนื่องจากtoJSONเป็นสิ่งประดิษฐ์ดั้งเดิมและแนวทางที่ดีกว่าคือการใช้แบบกำหนดเองreplacerโปรดดูhttps://github.com/DavidBruant/Map-Set.prototype.toJSON/issues/16 )

function Set_toJSON(key, value) {
  if (typeof value === 'object' && value instanceof Set) {
    return [...value];
  }
  return value;
}

จากนั้น:

const fooBar = { foo: new Set([1, 2, 3]), bar: new Set([4, 5, 6]) };
JSON.stringify(fooBar, Set_toJSON)

ผลลัพธ์:

"{"foo":[1,2,3],"bar":[4,5,6]}"

6
มีเวอร์ชันย่อใน ES6JSON.stringify(fooBar, (key, value) => value instanceof Set ? [...value] : value)
OzzyCzech

รีไวเวอร์ที่สอดคล้องกันทิ้งไว้เป็นแบบฝึกหัดสำหรับผู้อ่าน? ;-)
Robert Siemer

9

แม้ว่างานทั้งหมดข้างต้นฉันขอแนะนำให้คุณตั้งค่าคลาสย่อยและเพิ่มไฟล์ toJSONวิธีการเพื่อให้แน่ใจว่าสตริงนั้นถูกต้อง โดยเฉพาะอย่างยิ่งถ้าคุณจะต้องรัดเข็มขัดบ่อยๆ ฉันใช้ชุดในร้านค้า Redux ของฉันและต้องการให้แน่ใจว่านี่ไม่ใช่ปัญหา

นี่เป็นการใช้งานขั้นพื้นฐาน การตั้งชื่อเป็นเพียงการแสดงให้เห็นถึงจุดที่คุณเลือกสไตล์ของคุณเอง

class JSONSet extends Set {
    toJSON () {
        return [...this]
    }
}

const set = new JSONSet([1, 2, 3])
console.log(JSON.stringify(set))

4
ฉันจะไม่แนะนำวิธีนี้เนื่องจากtoJSONถือว่าเป็นคุณลักษณะดั้งเดิม ข้อเสนอที่จะเพิ่มtoJSONให้กับทั้งคู่setและmapถูกปฏิเสธ: github.com/DavidBruant/Map-Set.prototype.toJSON/issues/16
MitMaro

constructorไม่จำเป็นต้องลบล้าง
Justin Johnson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.