首页 > 解决方案 > 如何按值从 JSON 字符串中删除项目

问题描述

我在 C# 中工作。我想加载一个 JSON 字符串并按值删除一个项目。例如,在以下 JSON 中,我想删除 2 的值。因此,在生成的 JSON 字符串中,达拉斯商店应该已被删除。

[ 
   { 
      "text":"Select Store",
      "value":""
   },
   { 
      "text":"Austin Store",
      "value":"1"
   },
   { 
      "text":"Dallas Store",
      "value":"2"
   },
   { 
      "text":"Houston Store",
      "value":"3"
   },
   { 
      "text":"Chicago Store",
      "value":"4"
   },
   { 
      "text":"Los Angeles Store",
      "value":"5"
   }
]

我可以用 Newton Soft 的 JArray 解析字符串,循环遍历并将除 Dallas 之外的所有商店添加到新的 JArray 中。我想知道是否有一种更简单的 Linq 方法可以在 JArray 上工作,它将删除预期的项目。

标签: c#jsonjson.net

解决方案


JArray由于没有方法,因此您在这里有几个选择RemoveAll(Predicate<JToken> match)

首先,您可以使用SelectTokens()查找所有JArray项目,value == 2然后将其删除,如下所示:

var array = JArray.Parse(jsonString);

array.SelectTokens("[?(@.value == '2')]")
    .ToList()
    .ForEach(i => i.Remove());

该表达式[?(@.value == '2')]是一个 JSONPath 查询;有关详细信息和文档,请参阅# JSONPath - XPath for JSON和Querying JSON with complex JSON Path

请注意,这可能在要删除的项目数量方面具有二次性能,因此如果您要删除大量项目,则速度可能会慢得令人无法接受。

其次,您可以JTokenExtensions.RemoveAll(this JArray array, Predicate<JToken> match)这个答案中获取JArray - How to remove elements that are not included in another list -fastest/best performance way

public static partial class JTokenExtensions
{
    /// <summary>
    /// Removes all the elements that match the conditions defined by the specified predicate.
    /// </summary>
    public static void RemoveAll(this JArray array, Predicate<JToken> match)
    {
        if (array == null || match == null)
            throw new ArgumentNullException();
        array.ReplaceAll(array.Where(i => !match(i)).ToList());
    }
}

然后删除您想要的项目,如下所示:

array.RemoveAll(i => (string)i["value"] == "2");

这将在要删除的项目数量方面具有线性性能。

演示小提琴在这里


推荐阅读