c# - 反序列化未知维度的锯齿状数组

标签 c# json unity3d json.net jagged-arrays

我目前正在尝试使用 Json.NET 在 Unity 中解析 Json 文件,目前可以解析 80% 的数据。我遇到过这样格式的部分。

{
  "features": [
    {
      "coordinates": [
        [
          [ 1, 1 ],
          [ 2, 2 ]
        ]
      ]
    },
    {
      "coordinates": [
        [ 1, 1 ],
        [ 2, 2 ],
        [ 3, 3 ]
      ]
    },
    {
      "coordinates": [
        [
          [ 1, 2 ],
          [ 1, 2 ]
        ]
      ]
    },
    {
      "coordinates": [
        [
          [
            [ 1, 2 ],
            [ 1, 2 ]
          ]
        ]
      ]
    }
  ]
}

坐标数组可能包含未知数量的坐标,它也将是一个未知维度的锯齿状数组。我无法解析它,因为我不太精通 Json 反序列化。

感谢任何有关如何解决此问题的帮助。

最佳答案

我不确定您的数据有多少变化,但这里有一个使用递归的粗略想法。

    void ParseCoordinateJSON()
    {
        var coordinates = new List<int[]>();
        var parsed = JObject.Parse(rawJson);

        var featureArray = parsed.SelectToken("features");
        var coordArray = featureArray.Children();

        coordArray.ToList().ForEach(n => ExtractCoordinates(n.SelectToken("coordinates"), coordinates));

        Debug.Log(string.Join("\n", coordinates.Select(c => $"({string.Join(", ", c)})")));
    }

    void ExtractCoordinates(JToken node, List<int[]> coordinates)
    {
        if (node == null)
        {
            return;
        }

        if (node.Children().Any(n => n.Type == JTokenType.Integer))
        {
            coordinates.Add(node.Children().Select(n => n.Value<int>()).ToArray());
            return;
        }

        node.Children().Where(n => n.Type == JTokenType.Array).ToList().ForEach(n => ExtractCoordinates(n, coordinates));
    }

编辑: 这是没有 linq 的,可能更容易理解:

void ParseCoordinateJSONNoLinq()
{
    var coordinates = new List<int[]>();
    var parsed = JObject.Parse(rawJSON);

    var featureArray = parsed.SelectToken("features");

    // These will be the objects with a "coordinates" key and an array value.
    var coordArray = featureArray.Children();

    foreach(var node in coordArray)
    {
        ExtractCoordinatesNoLinq(node.SelectToken("coordinates"), coordinates);
    }

    Console.WriteLine(string.Join("\n", coordinates.Select(c => $"({string.Join(", ", c)})")));
}

void ExtractCoordinatesNoLinq(JToken node, List<int[]> coordinates)
{
    var intValues = new List<int>();

    // Step through each child of this node and do something based on its node type.
    foreach(var child in node.Children())
    {
        // If the child is an array, call this method recursively.
        if (child.Type == JTokenType.Array)
        {
            // Changes to the coordinates list in the recursive call will persist.
            ExtractCoordinatesNoLinq(child, coordinates);

        // The child type is an integer, add it to the int values.
        } else if (child.Type == JTokenType.Integer)
        {
            intValues.Add(child.Value<int>());
        }
    }

    // Since we found int values at this level, add them to the shared coordinates list.
    if (intValues.Count > 0)
    {
        coordinates.Add(intValues.ToArray());
    }
}

如果你的其余数据是可靠的,我会使用典型的数据对象并对它们进行反序列化,然后添加类似上面的内容作为 Custom JSON Converter。对于表示锯齿状数组的对象。

public class MyDataObject {
  public string SomeField {get; set;}

  public Vector2 Position {get; set;}

  [JsonProperty("features")]
  public JaggedFeatures {get; set;}
}

public class JaggedFeatures {
  public List<int[]> Coordinates {get; set;}
}

//...

JsonConvert.Deserialize<MyDataObject>(rawJSON, new JaggedFeaturesConverter())

关于c# - 反序列化未知维度的锯齿状数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59279008/

相关文章:

c# - 将 `Page` 替换为 `WinRTXamlToolkit.Controls.AlternativePage`

c# - 在 WPF 应用程序中找不到资源字典

iphone - 将我的 JSON 放入 tableView

c# - 如何以编程方式多次统一放置相同的 Sprite ?

c# - 光子 bolt |创建后将房间设为私有(private)

c# - 如何从一种形式获取值(value)到另一种形式?

c# - visual C#2010播放形式1的声音(来自资源文件)

java - JSONParser 中的方法 OnItemClickListener 覆盖另一个 Activity 中的 OnItemLongClickListener

java - 如何在 Java 中的 JSON 对象中访问此 key ?

c# - 如何在运行时将脚本添加到实例化对象?