【发布时间】:2009-10-07 23:03:03
【问题描述】:
如何将此 JSON 转换为具有两个属性第一个“id”和第二个“answer”的对象列表?
[["9","3"],["8","4"],["7","4"],["6","5"],["5","6"],["4","4"],["3","4"]]
【问题讨论】:
-
我假设您正在将此 JSON 对象传递给 Web 服务。您在服务器上使用 asmx 或 wcf 服务吗?
如何将此 JSON 转换为具有两个属性第一个“id”和第二个“answer”的对象列表?
[["9","3"],["8","4"],["7","4"],["6","5"],["5","6"],["4","4"],["3","4"]]
【问题讨论】:
我开始使用 JSON.NET - http://james.newtonking.com/pages/json-net.aspx 。它是一个非常全面的 JSON 库,几乎可以让您做任何事情。
【讨论】:
需要引用System.Web.Extensions 程序集;
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
【讨论】:
有 101 种方法,但这里有一个 .Net 2.0 字符串解析方法:
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 );
}
顺便说一句。由于您要提取名称值对,因此我只使用了一个 int/int 字典来保存数据。
【讨论】:
一个非常字面的答案。仅适用于您指定的确切格式,如果您传递意外数据可能会有点混乱。返回一个包含每一对的 KeyValuepair。
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));
【讨论】:
我认为最简单的工作方法是以下代码:
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);
}
}
}
当然结果包含一个“列表>”,这是您的 Json 字符串的正确类型。 您还必须记住添加对以下 dll 的引用:
【讨论】:
这是一个使用正则表达式的解决方案
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]);
添加:如果您希望结果值为 int 而不是字符串,那么您可以这样做
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("\"", "")));
【讨论】:
在 Silverlight 中,有 System.Json.dll 使 JSON 解析变得非常容易。有一些关于将其纳入 .NET4.0 的讨论,不确定是否发生。
在常规 .NET 中,您可以使用 DataContractJsonSerializer(使用 List> 之类的东西作为“类型”)。这适用于 .NET3.0 及更高版本。可能不是所有 JSON 解析场景的最佳选择(但适用于您的场景)。
【讨论】: