【问题标题】:How Do You Iterate Through An JObject If You Are Deleting Certain Elements?如果要删除某些元素,如何迭代 JObject?
【发布时间】:2019-12-26 23:27:48
【问题描述】:

总结:

通过美国教育部 API,我计划创建一份大学列表和计算机科学专业毕业生的工资中位数。但是,许多学校都有空值,并且尝试删除空值会破坏代码,因为在枚举时无法修改集合。

我的取消符代码:

static JObject DeNullifier(JObject inputJson)
{
    //Each school in the results[] section
    foreach(var school in inputJson["results"])
    {
        //Each degree in the cip_4_digit section
        foreach(var degree in school["latest.programs.cip_4_digit"])
        {
            if(string.IsNullOrEmpty(degree["earnings.median_earnings"].Value<string>()))
            {
                degree.Remove();
            }
        }
    }
    return inputJson;
}

JSON 缩短版:

{
    "metadata": 
    {
        "total": 1444,
        "page": 14,
        "per_page": 100
    },

    "results": 
    [
        {
            "school.name": "Georgia College & State University",
            "latest.programs.cip_4_digit": 
            [
                {
                  "earnings.median_earnings": 53200,
                  "title": "Computer Science.",
                  "code": "1107"
                }
            ]
        },
        {
            "school.name": "Georgia Southern University",
            "latest.programs.cip_4_digit": 
            [
                {
                  "earnings.median_earnings": null,
                  "title": "Computer Science.",
                  "code": "1107"
                }
            ]
        }
    ]
}

Newtonsoft JSON.NET 类参考:

https://www.newtonsoft.com/json/help/html/Methods_T_Newtonsoft_Json_Linq_JObject.htm

https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JToken.htm

https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JProperty.htm

【问题讨论】:

  • 您是否尝试使用该对象的副本
  • 我可以创建对象的副本,但删除副本不会对原始对象做任何事情。
  • 其实你只是给了我一个想法。创建一个新的 JObject,然后将有效元素添加到其中。唯一的缺点是效率低下,但我会尝试这种方法。
  • 无论如何您都在遍历整个 json,并且无法从您正在迭代的作业中删除。您可以将此项目用作骨架并从复制项目中删除
  • 创建一个副本也可以

标签: c# json collections json.net


【解决方案1】:

您可以将要删除的节点添加到不同的集合中,然后删除它们。例如,

static JObject DeNullifier(JObject inputJson)
{
    var nodesToRemove = new List<JToken>();
    //Each school in the results[] section
    foreach(var school in inputJson["results"])
    {
        //Each degree in the cip_4_digit section
        foreach(var degree in school["latest.programs.cip_4_digit"])
        {
            if(string.IsNullOrEmpty(degree["earnings.median_earnings"].Value<string>()))
            {
                nodesToRemove.Add(degree);
            }
        }
    }

    foreach(var node in nodesToRemove)
    {
        node.Remove();
    }
    return inputJson;
}

【讨论】:

    【解决方案2】:

    您可以通过将您的代码与标准Linq 中的Where 方法相结合来实现它(无需复制源集合)

    static JObject DeNullifier(JObject inputJson)
    {
        foreach (var school in inputJson["results"])
        {
            var degrees = (JArray)school["latest.programs.cip_4_digit"];
            var nullDegrees = degrees.Where(t => t["earnings.median_earnings"].Type == JTokenType.Null).ToList();
    
            foreach (var nullDegree in nullDegrees)
                degrees.Remove(nullDegree);
        }
    
        return inputJson;
    }
    

    您只需选择所有latest.programs.cip_4_digit 节点,其中earnings.median_earnings 值为空,然后从数组中删除这些项目。

    ToList() 会将具有空值的标记提升到新集合中,并有助于在删除期间避免InvalidOperationException

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多