有没有一种方法可以在数组中填充JSON对象中缺少的属性
本文关键字:JSON 填充 对象 属性 数组 一种 方法 有没有 | 更新日期: 2023-09-27 18:27:34
我在c#中使用JSON.NET来接触提供JSON作为输出的API。
我将输出作为CSV打印到控制台,以便powershell convertfrom-csv
、format-table
、select-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类型的操作,它可以在数组的所有元素中找到所有属性。
如果这是一个非常愚蠢的问题,我很抱歉,但我只是想知道这是否可能。
当然可以。有很多方法可以奏效。例如,您可以简单地进行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": ""
}
]
}