有没有一种方法可以在数组中填充JSON对象中缺少的属性

本文关键字:JSON 填充 对象 属性 数组 一种 方法 有没有 | 更新日期: 2023-09-27 18:27:34

我在c#中使用JSON.NET来接触提供JSON作为输出的API。

我将输出作为CSV打印到控制台,以便powershell convertfrom-csvformat-tableselect-object等可以使用它。

我有一个不错的通用方法,可以将所有类型的JSON打印为CSV,而且它几乎一直有效。

但是,在某些情况下,我会得到类似的JSON

{ 
    "result": 
    [ 
        { "product": "SP1", "version": "6.0" }, 
        { "product": "SP1 hf 40", "version": "6.0.40" }, 
        { "product": "SP1 hf 50", "version": "6.0.50" }, 
        { "version": "6.0.100" } 
    ] 
}

其中result中的最后一项完全缺少product属性。

有没有一种方法可以迭代result中的项,并放入缺失的属性,使输出为:

{ 
    "result": 
    [ 
        { "product": "SP1", "version": "6.0" }, 
        { "product": "SP1 hf 40", "version": "6.0.40" }, 
        { "product": "SP1 hf 50", "version": "6.0.50" }, 
        { "product": "", "version": "6.0.100" } 
    ] 
}

这将允许我继续使用将JSON输出打印为CSV的通用方法。

我的一个想法是遍历结果数组,找到具有最多属性的元素,并将其用作打印CSV的基础。

但这个想法表面上很平淡,因为属性的数量并不一定能保证整个集合中的所有属性。

我想我几乎需要一个UNION类型的操作,它可以在数组的所有元素中找到所有属性。

如果这是一个非常愚蠢的问题,我很抱歉,但我只是想知道这是否可能。

有没有一种方法可以在数组中填充JSON对象中缺少的属性

当然可以。有很多方法可以奏效。例如,您可以简单地进行2次传球。在第一次传递中,您建立了一个完整的属性列表,在第二次传递中输出到csv并带有完整的标题。

然而,无论你如何攻击它,这种规范化在流式传输时都不会很好。

我还想指出,Powershell 3.0及更高版本附带ConvertFrom Json。http://technet.microsoft.com/en-us/library/hh849898.aspx

是的,可以填充JSON中缺少的属性。以下是@BnWasterland:建议的使用两遍方法的示例

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""result"" : 
            [
                { ""a"" : ""a1"" },
                { ""b"" : ""b1"" },
                { ""c"" : ""c1"", ""d"" : ""d1"", ""a"" : ""a2"" },
                { ""a"" : ""a3"", ""d"" : ""d2"" },
                { ""b"" : ""b2"", ""c"" : ""c2"" },
            ]
        }";
        JObject jo = JObject.Parse(json);
        JArray ja = FillMissingProperties((JArray)jo["result"]);
        jo["result"] = ja;
        Console.WriteLine(jo.ToString());
    }
    public static JArray FillMissingProperties(JArray array)
    {
        // find all distinct property names across all objects in the array
        ISet<string> names = new SortedSet<string>();
        foreach (JObject obj in array.Children<JObject>())
        {
            foreach (JProperty prop in obj.Properties())
            {
                names.Add(prop.Name);
            }
        }
        // copy objects to a new array, adding missing properties along the way
        JArray arrayOut = new JArray();
        foreach (JObject obj in array.Children<JObject>())
        {
            JObject objOut = new JObject();
            foreach (string name in names)
            {
                JToken val = obj[name];
                if (val == null)
                {
                    val = new JValue("");
                }
                objOut.Add(name, val);
            }
            arrayOut.Add(objOut);
        }
        return arrayOut;
    }
}

输出:

{
  "result": [
    {
      "a": "a1",
      "b": "",
      "c": "",
      "d": ""
    },
    {
      "a": "",
      "b": "b1",
      "c": "",
      "d": ""
    },
    {
      "a": "a2",
      "b": "",
      "c": "c1",
      "d": "d1"
    },
    {
      "a": "a3",
      "b": "",
      "c": "",
      "d": "d2"
    },
    {
      "a": "",
      "b": "b2",
      "c": "c2",
      "d": ""
    }
  ]
}