Load a JSON string into a data structure. Also create a new data structure and serialize it into JSON. Use objects and arrays (as appropriate for your language) and make sure your JSON is valid (http://www.jsonlint.com/).

Task
JSON
You are encouraged to solve this task according to the task description, using any language you may know.

C#

Works with: C sharp version 3.0

This uses the JavaScriptSerializer class which was shipped with .NET 3.5.

<lang csharp>using System; using System.Collections.Generic; using System.Web.Script.Serialization;

class Program {

   static void Main()
   {
       var people = new Dictionary<string, object> {{"1", "John"}, {"2", "Susan"}};
       var serializer = new JavaScriptSerializer();
       
       var json = serializer.Serialize(people);
       Console.WriteLine(json);
       var deserialized = serializer.Deserialize<Dictionary<string, object>>(json);
       Console.WriteLine(deserialized["2"]);
       var jsonObject = serializer.DeserializeObject(@"{ ""foo"": 1, ""bar"": [10, ""apples""] }");
       var data = jsonObject as Dictionary<string, object>;
       var array = data["bar"] as object[];
       Console.WriteLine(array[1]);
   }

}</lang>

CoffeeScript

<lang coffeescript> sample =

 blue: [1, 2]
 ocean: 'water'
 

json_string = JSON.stringify sample json_obj = JSON.parse json_string

console.log json_string console.log json_obj </lang>

Clojure

<lang clojure>(ns json.example

 (:use [clojure.contrib.json]))
; Load as Clojure data structures and bind the resulting structure to 'json-map'.

(def json-map (read-json "{ \"foo\": 1, \"bar\": [10, \"apples\"] }"))

Use pr-str to print out the Clojure representation of the JSON created by read-json.

(pr-str json-map)

Pretty-print the Clojure representation of JSON. We've come full circle.

(pprint-json json-map)</lang>

Factor

<lang Factor> USING: json.writer json.reader ;

SYMBOL: foo

! Load a JSON string into a data structure "[[\"foo\",1],[\"bar\",[10,\"apples\"]]]" json> foo set


! Create a new data structure and serialize into JSON { { "blue" { "ocean" "water" } } >json </lang>

Fantom

<lang fantom> using util

class Json {

 public static Void main ()
 {
   Str input := """{"blue": [1, 2], "ocean": "water"}"""
   Map jsonObj := JsonInStream(input.in).readJson
   echo ("Value for 'blue' is: " + jsonObj["blue"])
   jsonObj["ocean"] = ["water":["cold", "blue"]]
   Map ocean := jsonObj["ocean"]
   echo ("Value for 'ocean/water' is: " + ocean["water"])
   output := JsonOutStream(Env.cur.out)
   output.writeJson(jsonObj)
   echo ()
 }

} </lang>

Output:

Value for 'blue' is: [1, 2]
Value for 'ocean/water' is: [cold, blue]
{"blue":[1,2],
"ocean":{"water":["cold","blue"]}}

Go

<lang go>package main import "json" import "fmt"

func main() {

   var data map[string]interface{}
   json.Unmarshal([]byte("{ \"foo\": 1, \"bar\": [10, \"apples\"] }"), &data)
   fmt.Println(data)
   sample := map[string]interface{}{ "blue": []interface{}{1,2}, "ocean": "water" }
   json_string, err := json.Marshal(sample)
   if err == nil {
       fmt.Println(string(json_string))
   } else {
       fmt.Println(err)
   }

}</lang>

J

Here is a minimal implementation based on an old email message.

<lang j>NB. character classes: NB. 0: whitespace NB. 1: " NB. 2: \ NB. 3: [ ] , { } : NB. 4: ordinary classes=.3<. '"\[],{}:' (#@[ |&>: i.) a. classes=.0 (I.a.e.' ',CRLF,TAB)} (]+4*0=])classes

words=:(0;(0 10#:10*".;._2]0 :0);classes)&;: NB. states:

 0.0  1.1  2.1  3.1  4.1  NB. 0 whitespace
 1.0  5.0  6.0  1.0  1.0  NB. 1 "
 4.0  4.0  4.0  4.0  4.0  NB. 2 \
 0.3  1.2  2.2  3.2  4.2  NB. 3 { : , } [ ]
 0.3  1.2  2.0  3.2  4.0  NB. 4 ordinary
 0.3  1.2  2.2  3.2  4.2  NB. 5 ""
 1.0  1.0  1.0  1.0  1.0  NB. 6 "\

)

tokens=. ;:'[ ] , { } :' actions=: lBra`rBracket`comma`lBra`rBracket`colon`value

NB. action verbs argument conventions: NB. x -- boxed json word NB. y -- boxed json state stack NB. result -- new boxed json state stack NB. NB. json state stack is an list of boxes of incomplete lists NB. (a single box for complete, syntactically valid json) jsonParse=: 0 {:: (,a:) ,&.> [: actions@.(tokens&i.@[)/ [:|.a:,words

lBra=: a: ,~ ] rBracket=: _2&}.@], [:< _2&{::@], _1&{@] comma=: ] rBrace=: _2&}.@], [:< _2&{::@], [:|: (2,~ [: -:@$ _1&{@]) $ _1&{@] colon=: ] value=: _1&}.@], [:< _1&{::@], jsonValue&.>@[

NB. hypothetically, jsonValue should strip double quotes NB. interpret back slashes NB. and recognize numbers jsonValue=:]


require'strings' jsonSer1=: ']' ,~ '[' }:@;@; (',' ,~ jsonSerialize)&.> jsonSer0=: '"', jsonEsc@:":, '"'"_ jsonEsc=: rplc&(<;._1' \ \\ " \"') jsonSerialize=:jsonSer0`jsonSer1@.(*@L.)</lang>

Example use:

<lang> jsonParse'{ "blue": [1,2], "ocean": "water" }' ┌──────────────────────────────┐ │┌──────┬─────┬───────┬───────┐│ ││"blue"│┌─┬─┐│"ocean"│"water"││ ││ ││1│2││ │ ││ ││ │└─┴─┘│ │ ││ │└──────┴─────┴───────┴───────┘│ └──────────────────────────────┘

  jsonSerialize jsonParse'{ "blue": [1,2], "ocean": "water" }'

[["\"blue\"",["1","2"],"\"ocean\"","\"water\""]]</lang>

Note that these are not strict inverses of each other. These routines allow data to be extracted from json and packed into json format, but only in a minimalistic sense. No attempts are made to preserve the subtleties of type and structure which json can carry. This should be good enough for most applications which are required to deal with json but will not be adequate for ill behaved applications which exploit the typing mechanism to carry significant information.

Also, a different serializer will probably be necessary, if you are delivering json to legacy javascript. Nevertheless, these simplifications are probably appropriate for practical cases.

JavaScript

Requires JSON library, now present in some browsers. <lang JavaScript>var data = JSON.parse('{ "foo": 1, "bar": [10, "apples"] }');

var sample = { "blue": [1,2], "ocean": "water" }; var json_string = JSON.stringify(sample);</lang>

Of course, it IS called JavaScript Object Notation, so it is a JavaScript object literal, and you can, alternately, parse it by just eval'ing it. This should work in any browser without a library. (Eval may be dangerous, depending on the source of the data.) However, there is an ambiguity with parsing JavaScript object literals by themselves, where it might be mistakenly interpreted as a block, and the key followed by a colon as a label. To avoid this, remember to surround it in parentheses to force it to be interpreted as an expression: <lang javascript>var data = eval('(' + '{ "foo": 1, "bar": [10, "apples"] }' + ')');</lang>

OCaml

compile with:

ocamlfind opt -o j.opt j.ml -linkpkg -package json-static -syntax camlp4o

<lang ocaml>type json item =

 < name    "Name": string;
   kingdom "Kingdom": string;
   phylum  "Phylum": string;
   class_  "Class": string;
   order   "Order": string;
   family  "Family": string;
   tribe   "Tribe": string
 >

let str = "

 {
   \"Name\":    \"camel\",
   \"Kingdom\": \"Animalia\",
   \"Phylum\":  \"Chordata\",
   \"Class\":   \"Mammalia\",
   \"Order\":   \"Artiodactyla\",
   \"Family\":  \"Camelidae\",
   \"Tribe\":   \"Camelini\"
 }"

let () =

 let j = Json_io.json_of_string str in
 print_endline (Json_io.string_of_json j);</lang>

OpenEdge/Progress

The WRITE-JSON and READ-JSON methods were introduced in Progress OpenEdge 10.2B. <lang progress>/* using a longchar to read and write to, can also be file, memptr, stream */ DEFINE VARIABLE lcjson AS LONGCHAR NO-UNDO.

/* temp-table defines object, can also be dataset */ DEFINE TEMP-TABLE example

  FIELD blue  AS INTEGER EXTENT 2
  FIELD ocean AS CHARACTER
  .

CREATE example. ASSIGN

  example.blue [1]  =  1
  example.blue [2]  =  2
  example.ocean     =  "water"
  .

/* write-json to put result in lcjson, true indicates formatted */ TEMP-TABLE example:DEFAULT-BUFFER-HANDLE:WRITE-JSON( "LONGCHAR", lcjson, TRUE ).

/* display result */ MESSAGE

  STRING( lcjson )

VIEW-AS ALERT-BOX.

/* empty results */ EMPTY TEMP-TABLE example.

/* read-json to get result from lcjson */ TEMP-TABLE example:DEFAULT-BUFFER-HANDLE:READ-JSON( "LONGCHAR", lcjson ).

FIND example. /* display results */ MESSAGE

  example.blue [1] example.blue [2] SKIP
  example.ocean

VIEW-AS ALERT-BOX.</lang>

Output write-json:

---------------------------
Message
---------------------------
{"example": [
  {
    "blue": [
      1,
      2
    ],
    "ocean": "water"
  }
]}
---------------------------
OK   
---------------------------

Output read-json:

---------------------------
Message
---------------------------
1 2 
water
---------------------------
OK   
---------------------------

Oz

With the JSON library from here: <lang oz>declare

 [JSON] = {Module.link ['JSON.ozf']}
 {System.show {JSON.decode "{ \"foo\": 1, \"bar\": [10, \"apples\"] }"}}
 Sample = object(blue:array(1 2) ocean:"water")
 {System.showInfo {JSON.encode Sample}}</lang>

Output:

object(bar:array(10 [97 112 112 108 101 115]) foo:1)
{"blue":[1,2],"ocean":"water"}

Perl

Library: JSON

<lang perl>use JSON;

my $data = decode_json('{ "foo": 1, "bar": [10, "apples"] }');

my $sample = { blue => [1,2], ocean => "water" }; my $json_string = encode_json($sample);</lang>

Perl 6

Using [1]

<lang perl> use JSON::Tiny;

my $data = from-json('{ "foo": 1, "bar": [10, "apples"] }');

my $sample = { blue => [1,2], ocean => "water" }; my $json_string = to-json($sample); </lang>

PHP

<lang php><?php $data = json_decode('{ "foo": 1, "bar": [10, "apples"] }'); // dictionaries will be returned as objects $data2 = json_decode('{ "foo": 1, "bar": [10, "apples"] }', true); // dictionaries will be returned as arrays

$sample = array( "blue" => array(1,2), "ocean" => "water" ); $json_string = json_encode($sample); ?></lang>

PicoLisp

PicoLisp has no JSON library, but it is easy enough to write one: <lang PicoLisp>(de checkJson (X Item)

  (unless (= X Item)
     (quit "Bad JSON" Item) ) )

(de readJson ()

  (case (read "_")
     ("{"
        (make
           (for (X (readJson)  T  (readJson))
              (checkJson ":" (readJson))
              (link (cons X (readJson)))
              (T (= "}" (setq X (readJson))))
              (checkJson "," X) ) ) )
     ("["
        (make
           (link T)  # Array marker
           (for (X (readJson)  T  (readJson))
              (link X)
              (T (= "]" (setq X (readJson))))
              (checkJson "," X) ) ) )
     (T @) ) )

(de printJson (Item) # For simplicity, without indentation

  (cond
     ((atom Item) (print Item))
     ((=T (car Item))
        (prin "[")
        (map
           '((X)
              (printJson (car X))
              (and (cdr X) (prin ", ")) )
           (cdr Item) )
        (prin "]") )
     (T
        (prin "{")
        (map
           '((X)
              (print (caar X))
              (prin ": ")
              (printJson (cdar X))
              (and (cdr X) (prin ", ")) )
           Item )
        (prin "}") ) ) )</lang>

This reads/prints JSON from/to files, pipes, sockets etc. To read from a string, a pipe can be used:

: (pipe (prinl "{ \"foo\": 1, \"bar\": [10, \"apples\"] }")
   (readJson) )
-> (("foo" . 1) ("bar" T 10 "apples"))

: (printJson
   (quote
      ("name" . "Smith")
      ("age" . 25)
      ("address"
         ("street" . "21 2nd Street")
         ("city" . "New York")
         ("state" . "NY")
         ("zip" . "10021") )
      ("phone" T "212 555-1234" "646 555-4567") ) )
{"name": "Smith", "age": 25, ... {"street": ... "phone": ["212 555-1234", ...

Python

Works with: Python version 2.6+
Works with: Python version 3.0+

<lang Python>>>> import json >>> data = json.loads('{ "foo": 1, "bar": [10, "apples"] }') >>> sample = { "blue": [1,2], "ocean": "water" } >>> json_string = json.dumps(sample) >>> json_string '{"blue": [1, 2], "ocean": "water"}' >>> sample {'blue': [1, 2], 'ocean': 'water'} >>> data {'foo': 1, 'bar': [10, 'apples']}</lang>

Because most of JSON is valid Python syntax (except "true", "false", and "null", and a few obscure escape sequences), it is also possible (but not recommended) to parse JSON using eval(): <lang python>>>> true = True; false = False; null = None >>> data = eval('{ "foo": 1, "bar": [10, "apples"] }') >>> data {'foo': 1, 'bar': [10, 'apples']}</lang>

REBOL

Using json.org/json.r

<lang rebol>json-str: {{"menu": {

   "id": "file",
   "string": "File:",
   "number": -3,
   "boolean": true,
   "boolean2": false,
   "null": null,
   "array": [1, 0.13, null, true, false, "\t\r\n"],
   "empty-string": ""
 }

}}

res: json-to-rebol json-str js: rebol-to-json res </lang>

json-to-rebol Result:

make object! [
    menu: make object! [
        id: "file"
        string: "File:"
        number: -3
        boolean: true
        boolean2: false
        null: none
        array: [1 0.13 none true false "^-^M^/"]
        empty-string: ""
    ]
]


rebol-to-json Result:

{
    "menu": {
        "id": "file",
        "string": "File:",
        "number": -3,
        "boolean": true,
        "boolean2": false,
        "null": null,
        "array": [1, 0.13, null, true, false, "\t\r\n"],
        "empty-string": ""
    }
}

Ruby

Uses

Library: RubyGems

package json

<lang ruby>require 'json' ruby_obj = JSON.parse('{"blue": [1, 2], "ocean": "water"}') p ruby_obj puts ruby_obj.class puts ruby_obj["blue"].class ruby_obj["ocean"] = {"water" => %w{fishy salty}} puts JSON.generate(ruby_obj)</lang>

Outputs

{"blue"=>[1, 2], "ocean"=>"water"}
Hash
Array
{"blue":[1,2],"ocean":{"water":["fishy","salty"]}}

Tcl

For parsing JSON,

Library: Tcllib (Package: json)

provides the capability (see the Tcler's Wiki page on it for more discussion):

<lang tcl>package require json set sample {{ "foo": 1, "bar": [10, "apples"] }}

set parsed [json::json2dict $sample] puts $parsed</lang> Output:

foo 1 bar {10 apples}

However, that package is very weak in its generation of JSON because Tcl's official type system is substantially different to that envisaged by JSON. It's possible to work around this though the use of Tcl 8.6, as this next example shows:

Works with: Tcl version 8.6

<lang tcl>package require Tcl 8.6

proc tcl2json value {

   # Guess the type of the value; deep *UNSUPPORTED* magic!
   regexp {^value is a (.*?) with a refcount} \

[::tcl::unsupported::representation $value] -> type

   switch $type {

string { # Skip to the mapping code at the bottom } dict { set result "{" set pfx "" dict for {k v} $value { append result $pfx [tcl2json $k] ": " [tcl2json $v] set pfx ", " } return [append result "}"] } list { set result "\[" set pfx "" foreach v $value { append result $pfx [tcl2json $v] set pfx ", " } return [append result "\]"] } int - double { return [expr {$value}] } booleanString { return [expr {$value ? "true" : "false"}] } default { # Some other type; do some guessing... if {$value eq "null"} { # Tcl has *no* null value at all; empty strings are semantically # different and absent variables aren't values. So cheat! return $value } elseif {[string is integer -strict $value]} { return [expr {$value}] } elseif {[string is double -strict $value]} { return [expr {$value}] } elseif {[string is boolean -strict $value]} { return [expr {$value ? "true" : "false"}] } }

   }
   # For simplicity, all "bad" characters are mapped to \u... substitutions
   set mapped [subst -novariables [regsub -all {[][\u0000-\u001f\\""]} \

$value {[format "\\\\u%04x" [scan {& } %c]]}]]

   return "\"$mapped\""

}</lang> Sample code (note that the value is built with dict create and list so that there is some auxiliary type hints available, which the above procedure can read): <lang tcl>set d [dict create blue [list 1 2] ocean water] puts [tcl2json $d]</lang> Output:

{"blue": [1, 2], "ocean": "water"}

Note that this is capable of correctly handling the round-trip of values parsed from the json package described above.