tags:

views:

322

answers:

7

how can i turn this JSON to a list of objects that have two properties first "id" and second "answer" ?

[["9","3"],["8","4"],["7","4"],["6","5"],["5","6"],["4","4"],["3","4"]]
+2  A: 

There's 101 ways but here's a .Net 2.0 string parse method:

        Dictionary<int, int> jsonValues = new Dictionary<int, int>();

        string data = "[[\"9\",\"3\"],[\"8\",\"4\"],[\"7\",\"4\"],[\"6\",\"5\"],[\"5\",\"6\"],[\"4\",\"4\"],[\"3\",\"4\"]]";

        string[] items = data.Split(new string[]{"\"],[\""}, StringSplitOptions.RemoveEmptyEntries);

        foreach (string str in items)
        {
            string[] intVals = str
                .Replace("\"", "")
                .Replace("[", "")
                .Replace("[", "")
                .Replace("]", "").Split(',');

            jsonValues.Add(int.Parse(intVals[0]), int.Parse(intVals[1]));
        }

        // test print:
        foreach (KeyValuePair<int,int> kvp in jsonValues)
        {
            System.Diagnostics.Debug.WriteLine(
                "ID:" + kvp.Key + " val:" + kvp.Value );
        }

by the way. Since you're extracting name value pairs i just used a dictionary of int/int to hold the data.

Paul Sasik
Looks good :) thx
Yassir
You're welcome. If you want a tighter or perhaps faster algorithm i'd recommend using RegEx and matching for groups of "<int>,<int>". But that's not something i can bang out very quickly.
Paul Sasik
thx a lot but with RegEx i ll have something else to wory about !!
Yassir
A: 

Here is a solution using RegEx

string data = "[[\"9\",\"3\"],[\"8\",\"4\"],[\"7\",\"4\"],[\"6\",\"5\"],[\"5\",\"6\"],[\"4\",\"4\"],[\"3\",\"4\"]]";

var pairs = (from Match m in Regex.Matches(data, "\"[0-9]\"\\,\"[0-9]\"") 
             select m.Value.Split(',')).ToDictionary(d => d[0], d => d[1]);

Added: if you want the resulting values as int instead of strings then you can do this instead

var pairs = (from Match m in Regex.Matches(data, "\"[0-9]\"\\,\"[0-9]\"") 
        select m.Value.Split(','))
       .ToDictionary(d => Int32.Parse(d[0].Replace("\"", "")), 
                     d => Int32.Parse(d[1].Replace("\"", "")));
Roatin Marth
Good looking RegEx solution but the match depends on single character integers. Yassir's sample data does happen to only contain single-character integers in this case but that might not be the case for a all runs of the algorithm. So the [0-9] match needs to be replaced with a \d (\d = n-length integers)
Paul Sasik
Agreed, it can be made more flexible if need be with minor changes to the regex.
Roatin Marth
thank you it work just fine :)
Yassir
@Roatin Marth, @Yassir: could you guys take a look into my answer below? I love regexs but in this case I chose to use JavaScriptSerializer() which seems to fit better; ty!
Rubens Farias
fyi, the minor regex change is:\"[0-9]\"\\,\"[0-9]\"to\"\d+?\"\\,\"\d+?\"
Gregory
+5  A: 

I started using JSON.NET - http://james.newtonking.com/pages/json-net.aspx . Its a very comprehensive JSON library that allows you to do pretty much anything.

Igor Zevaka
A: 

In Silverlight, there's System.Json.dll that makes JSON parsing very easy. There was some talk of getting it into .NET4.0, not sure if it happened.

In regular .NET, you can use the DataContractJsonSerializer (use something like List> as the "type"). This works in .NET3.0 and above. May not be the best choice for all JSON parsing scenarios (but will work for yours).

Eugene Osovetsky
+1  A: 

a very literal answer. Will only work for the exact format you specified, may go a little haywire if you pass it unexpected data. Returns a KeyValuepair with each pair in it.

        var val = "[[\"9\",\"3\"],[\"8\",\"4\"],[\"7\",\"4\"],[\"6\",\"5\"],[\"5\",\"6\"],[\"4\",\"4\"],[\"3\",\"4\"]]";

        var result = val.ToCharArray()
            .Where(itm => Char.IsDigit(itm))
            .Select((itm, index) => new {c = int.Parse(itm.ToString()),index = index + 1})
            .GroupBy(itm => itm.index % 2 == 0 ? itm.index - 1 : itm.index)
            .Select(itm => new KeyValuePair<int, int>(itm.ElementAt(0).c, itm.ElementAt(1).c));
Gregory
+4  A: 

Requires reference to System.Web.Extensions assembly;

using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Web.Script.Serialization;

class Program
{
    public class Test
    {
        public string Id { get; set; }
        public string Answer { get; set; }
    }

    static void Main(string[] args)
    {
        string data ="[[\"9\",\"3\"],[\"8\",\"4\"],[\"7\",\"4\"],[\"6\",\"5\"]]";
        List<Test> tests = 
            Array.ConvertAll<ArrayList, Test>(
                new JavaScriptSerializer()
                    .Deserialize<ArrayList>(data)
                        .OfType<ArrayList>().ToArray(), 
               (item) =>
               {
                   return new Test()
                   {
                       Id = (string)item[0],
                       Answer = (string) item[1]
                   };
               }).ToList();
    }
}

ROFL, HTH

Rubens Farias
+1  A: 

I think the easyiest way to the job is the following piece of code:

using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

namespace JsonParser
{
    class Program
    {
     static void Main(string[] args)
     {
      string data = "[[\"9\",\"3\"],[\"8\",\"4\"],[\"7\",\"4\"],[\"6\",\"5\"],[\"5\",\"6\"],[\"4\",\"4\"],[\"3\",\"4\"]]";
      var stream = new MemoryStream(new ASCIIEncoding().GetBytes(data));
      var deserializer = new DataContractJsonSerializer(typeof(List<List<string>>));
      var result = (List<List<string>>)deserializer.ReadObject(stream);
     }
    }
}

of course result contains a "List>" which is the correct type of your Json string. Also you have to remember to add references to the following dlls:

  • System.Runtime.Serialization
  • System.ServiceModel.Web
Carlos Muñoz