Sets plus JSON

Allen Wirfs-Brock allen at wirfs-brock.com
Thu Oct 4 22:33:23 PDT 2012


On Oct 4, 2012, at 9:02 PM, Rick Waldron wrote:

> 
> 
> On Thursday, October 4, 2012 at 9:29 PM, Allen Wirfs-Brock wrote:
> 
>> 
>> On Oct 4, 2012, at 5:32 PM, Rick Waldron wrote:
>> 
>>> 
>>> 
>>> On Thu, Oct 4, 2012 at 8:16 PM, Brendan Eich <brendan at mozilla.org> wrote:
>>>> Nicholas C. Zakas wrote:
>>>>> I agree, I'm not sure there is a rational default for Map, but I think there is one for Set as an array (and it seems like most people agreed).
>>>> 
>>>> As with Set, I claim the default JSON for Map should be
>>>> 
>>>>   [[key1, value1], ~~~ [keyN, valueN]]
>>> 
>>> 
>>> I'm still curious about my question from yesterday; instead of repasting, I put it in a gist:
>>> 
>>> https://gist.github.com/3837337
>>> 
>> 
>> 
>> Something like: 
>> 
>>           {"<kind>" : "Map",
>>            "<mapData>" : [
>>                       [ key1, value1],
>>                       [ keyN, valueN]
>>                       ]
>>              }
>> 
>> is arguably a better because then you can write a  reviver function that recognizes it:
>> 
>> function mapReviver(key, value) {
>>    if (typeof value != "object") return value;
>>    switch (value["<kind>"]) {
>>       case undefined: return value;
>>       case "Map": {
>>          let newValue = new Map;
>>          let mapData = value["<mapData>"];
>>          if (!mapData) return value;
>>          mapData.forEach(function(e){newValue.set(e[0], e[1])});
>>          return newValue;
>>          }
>>       default: return value;
>>     }
>> }
>> function mapReviver(key, value) {
>>    if (typeof value != "object") return value;
>>    switch (value["<kind>"]) {
>>       case undefined: return value;
>>       case "Map": {
>>          let newValue = new Map;
>>          let mapData = value["<mapData>"];
>>          if (!mapData) return value;
>>          mapData.forEach(function(e){newValue.set(e[0], e[1])});
>>          return newValue;
>>          }
>>       default: return value;
>>     }
>> }
>> function mapReviver(key, value) {
>>    if (typeof value != "object") return value;
>>    switch (value["<kind>"]) {
>>       case undefined: return value;
>>       case "Map": {
>>          let newValue = new Map;
>>          let mapData = value["<mapData>"];
>>          if (!mapData) return value;
>>          mapData.forEach(function(e){newValue.set(e[0], e[1])});
>>          return newValue;
>>          }
>>       default: return value;
>>     }
>> }
>> function mapReviver(key, value) {
>>    if (typeof value != "object") return value;
>>    switch (value["<kind>"]) {
>>       case undefined: return value;
>>       case "Map": {
>>          let newValue = new Map;
>>          let mapData = value["<mapData>"];
>>          if (!mapData) return value;
>>          mapData.forEach(function(e){newValue.set(e[0], e[1])});
>>          return newValue;
>>          }
>>       default: return value;
>>     }
>> }
>> function mapReviver(key, value) {
>>    if (typeof value != "object") return value;
>>    switch (value["<kind>"]) {
>>       case undefined: return value;
>>       case "Map": {
>>          let newValue = new Map;
>>          let mapData = value["<mapData>"];
>>          if (!mapData) return value;
>>          mapData.forEach(function(e){newValue.set(e[0], e[1])});
>>          return newValue;
>>          }
>>       default: return value;
>>     }
>> }
>> function mapReviver(key, value) {
>>    if (typeof value != "object") return value;
>>    switch (value["<kind>"]) {
>>       case undefined: return value;
>>       case "Map": {
>>          let newValue = new Map;
>>          let mapData = value["<mapData>"];
>>          if (!mapData) return value;
>>          mapData.forEach(function(e){newValue.set(e[0], e[1])});
>>          return newValue;
>>          }
>>       default: return value;
>>     }
>> }
>> function mapReviver(key, value) {
>>    if (typeof value != "object") return value;
>>    switch (value["<kind>"]){
>>       case undefined: return value;
>>       case "Map": {
>>          let newValue = new Map;
>>          let mapData = value["<mapData>"];
>>          if (!mapData) return value;
>>          mapData.forEach(e=>newValue.set(e[0], e[1]));
>>          return newValue;
>>          }
>>       default: return value;
>>     }
>> }
>> 
>> var tree = JSON.parse(sourceString, mapReviver);
> 
> But, this still doesn't explain how an object-as-key gets its reference put back into (the correct) scope :)


Ah, it doesn't by itself.  JSON serialization doesn't preserve identify either within a single JSON document or with source or target object context. Admittedly an issue if you need to serialize a Map that has object keys.   You need to add an identify mapping layer to the JSON scheme you produce to make something like that work.  Again, these are things that probably don't have a general solution and are probably better handled close to the application layer.

Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121004/751710e5/attachment.html>


More information about the es-discuss mailing list