Reputation: 194
Is it possible to convert a list of objects from json to an 2D array?
Data.json
{
"x": 6,
"y": 6,
"information": [
{
"x": 0,
"y": 0,
"info": "First item",
"info2": 1
},
{
"x": 1,
"y": 3,
"info": "Second item",
"info2": 3
},
{
"x": 3,
"y": 4,
"info": "Third item",
"info2": 2
}
]
}
The first x and y are the size of the 2D array. Is it possible to use the Custom JsonConverter to put the information list into this array based on the x and y of the info objects? I know that it could be possible to convert it first into a list and then without Json.net into an array, but would it be possible while deseriliazing?
Upvotes: 0
Views: 748
Reputation: 29836
I've created a custom converter for you:
Poco:
public class Item
{
[JsonProperty("x")]
public int X { get; set; }
[JsonProperty("y")]
public int Y { get; set; }
[JsonProperty("info")]
public string Info { get; set; }
[JsonProperty("info2")]
public string Info2 { get; set; }
}
Converter:
public class ItemJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Item[,]);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
var x = jObject.Value<int>("x");
var y = jObject.Value<int>("y");
var items = jObject.GetValue("information").ToObject<IEnumerable<Item>>();
var itemsArray = new Item[x, y];
foreach (var item in items)
{
itemsArray[item.X, item.Y] = item;
}
return itemsArray;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Usage:
var jsonStr = @"{
""x"": 3,
""y"": 1,
""information"": [
{
""x"": 0,
""y"": 0,
""info"": ""First item"",
""info2"": 1
},
{
""x"": 1,
""y"": 0,
""info"": ""Second item"",
""info2"": 3
},
{
""x"": 2,
""y"": 0,
""info"": ""Third item"",
""info2"": 2
}
]
}";
var jss = new JsonSerializerSettings();
jss.Converters.Add(new ItemJsonConverter());
var obj = JsonConvert.DeserializeObject<Item[,]>(jsonStr, jss);
Upvotes: 1
Reputation: 16672
Maybe the simplest/fastest way is to do it manually, like this:
using Newtonsoft.Json;
namespace WpfApplication3
{
public partial class MainWindow
{
private readonly string json = @"
{
""x"": 6,
""y"": 6,
""information"": [
{
""x"": 0,
""y"": 0,
""info"": ""First item"",
""info2"": 1
},
{
""x"": 1,
""y"": 3,
""info"": ""Second item"",
""info2"": 3
},
{
""x"": 3,
""y"": 4,
""info"": ""Third item"",
""info2"": 2
}
]
}";
public MainWindow()
{
InitializeComponent();
var o = JsonConvert.DeserializeObject<SampleResponse1>(json);
var array = new IInformation[o.X, o.Y];
foreach (var i in o.Information)
{
array[i.X, i.Y] = i;
}
}
}
internal class SampleResponse1
{
[JsonProperty("x")]
public int X { get; set; }
[JsonProperty("y")]
public int Y { get; set; }
[JsonProperty("information")]
public Information[] Information { get; set; }
}
internal class Information : IInformation
{
[JsonProperty("x")]
public int X { get; set; }
[JsonProperty("y")]
public int Y { get; set; }
#region IInformation Members
[JsonProperty("info")]
public string Info { get; set; }
[JsonProperty("info2")]
public int Info2 { get; set; }
#endregion
}
internal interface IInformation
{
string Info { get; set; }
int Info2 { get; set; }
}
}
Note that I didn't really bother, just used an interface to hide x
and y
, feel free to further tune it.
Also, I used http://jsonclassgenerator.codeplex.com/ to convert to classes.
Upvotes: 0