如何通过匹配值从JSON字符串中的特定属性中删除值?

时间:2021-03-09 20:57:44

I have a JSON string like this:

我有一个像这样的JSON字符串:

{"Country":"USA","States":["Chicago","Miami"]}

public string Remove(string json)
{
    string[] stateFilter = { "Chicago", "Miami"};
    foreach (var state in stateFilter)
    {
        //here I would like to create new copy of json for each state.
        string newJson = {"Country":"USA","States":["Chicago"]}  // Removed Miami from json for Chicago
    }
}

Now I would like to create a new JSON string for each state by finding the state in the JSON and removing it from the JSON string. So each state will contain its new copy of the JSON and will not contain any other state.

现在,我想通过在JSON中查找状态并从JSON字符串中删除它来为每个状态创建一个新的JSON字符串。因此每个州都将包含其JSON的新副本,并且不包含任何其他状态。

For example: Chicago will contain Chicago in JSON States Property.

例如:芝加哥将在JSON States Property中包含Chicago。

Code I am trying:

我正在尝试的代码:

public string Remove(string json)
{
    string[] stateFilter = { "Chicago", "Miami"};
    foreach (var state in stateFilter)
    {
        var jArr = JArray.Parse(json);

        jArr.Descendants().OfType<JProperty>()
            .Where(p => p.Name == state)
            .ToList()
            .ForEach(att => att.Remove());
    }
}

But the above code removes the property instead of the value from the JSON string.

但是上面的代码删除了属性而不是JSON字符串中的值。

4 个解决方案

#1


1  

This solution based on your specification: So each state will contain its new copy of json and will not contain any other state

此解决方案基于您的规范:因此每个州将包含其json的新副本,并且不包含任何其他状态

You can use Newtonsoft json serializer to deserialize json create new instance for every state and serialize them back to json

您可以使用Newtonsoft json序列化程序反序列化json为每个状态创建新实例并将它们序列化回json

public class States
{
    public string Country { get; set; }
    public List<string> States { get; set; }        
}

public IEnumerable<string> GenerateSeparatedListOfStates(string json)
{
    var original = JsonConvert.DeserializaeObject<States>(json);

    foreach(string state in original.States)
    {
        var temp = new States 
        { 
            Country = state.Country,
            States = new List<string> { state }
        }
        yield return JsonConvert.SerializeObject(temp);
    }
}

#2


1  

You need deserialize your json into object, remove the object which you don't need from the States List and after that serialize it again.

您需要将json反序列化为对象,从States List中删除不需要的对象,然后再将其序列化。

    public class JsonClass
    {
        public string Country { get; set; }

        public List<string> States { get; set; }
    }


    static void Main(string[] args)
    {
        string json = @"{""Country"":""USA"",""States"":[""Chicago"",""Miami""]}";

        JsonClass className  = JsonConvert.DeserializeObject<JsonClass>(json);

        className.States.Remove("Miami");

        Console.WriteLine(JsonConvert.SerializeObject(className));

    }

Edit:

编辑:

About your question: remove all elements without Chicago:

关于你的问题:删除没有芝加哥的所有元素:

Change line:

换线:

className.States.Remove("Miami");

To:

至:

className.States.RemoveAll(x => x != "Chicago");

#3


1  

I've read all your question and all the comments to the other answers, and quite frankly I'm still unsure if this will answer what I think you are asking!

我已经阅读了你的所有问题以及对其他答案的所有评论,坦率地说,我仍然不确定这是否能回答我的想法!

This code does not require any external library, you simply need to add a reference to System.Web.Extensions to your project.

此代码不需要任何外部库,您只需要向项目添加对System.Web.Extensions的引用。

string jsonString = "{\"Country\":\"USA\",\"States\":[\"Chicago\",\"Miami\"]}";
var jss = new JavaScriptSerializer();
dynamic json = jss.DeserializeObject(jsonString);
var statesToRemove = new object[] { "Chicago", "Miami" };
object[] originalStates = json["States"] as object[];
foreach(var state in statesToRemove)
{
    json["States"] = new[] { state }; 
    string newJson = jss.Serialize(json);
}
// Outputs...
// {"Country":"USA","States":["Chicago"]}
// {"Country":"USA","States":["Miami"]}

We deserialize the json to an object graph and traverse it dynamically (using dynamic - this is how json["States"] even compiles). For each state in the statesToRemove collection, we serialize a new json string with that as the only state.

我们将json反序列化为对象图并动态遍历它(使用动态 - 这就是json [“States”]甚至编译的方式)。对于statesToRemove集合中的每个状态,我们将新的json字符串序列化为唯一的状态。

#4


1  

If you're just looking for a way to copy the JSON and replace the States array with just a single, known state, you could make your method like this:

如果你只是想找到一种方法来复制JSON并用一个已知的状态替换States数组,你可以像这样制作你的方法:

public static string Remove(string json, string stateToKeep)
{
    JObject jo = JObject.Parse(json);
    jo["States"] = new JArray(stateToKeep);
    return jo.ToString();
}

Fiddle: https://dotnetfiddle.net/hVz6yF

小提琴:https://dotnetfiddle.net/hVz6yF

If you're looking to do this for all the states in the States array without knowing in advance what they all are, you could do something like this instead:

如果你想在不知道它们都是什么的情况下为States数组中的所有状态执行此操作,则可以执行以下操作:

public static string Remove(string json)
{
    var obj = JObject.Parse(json);
    var result = obj["States"].Select(s =>
    {
        var clone = s.Root.DeepClone();
        clone["States"] = new JArray(s);
        return clone;
    });
    return new JArray(result).ToString();
}

Basically, we parse the JSON to a JObject, then iterate over the states using Select. For each state, we clone the entire JSON, then replace the clones' States array with a new JArray containing just the single state. Lastly, we put all these clones into a new JArray and convert it to string.

基本上,我们将JSON解析为JObject,然后使用Select迭代状态。对于每个状态,我们克隆整个JSON,然后用仅包含单个状态的新JArray替换克隆的States数组。最后,我们将所有这些克隆放入一个新的JArray并将其转换为字符串。

Given your original JSON, you would end up with this new result:

鉴于您的原始JSON,您最终会得到这个新结果:

[
  {
    "Country": "USA",
    "States": [
      "Chicago"
    ]
  },
  {
    "Country": "USA",
    "States": [
      "Miami"
    ]
  }
]

Fiddle: https://dotnetfiddle.net/qb4fu0

小提琴:https://dotnetfiddle.net/qb4fu0

#1


1  

This solution based on your specification: So each state will contain its new copy of json and will not contain any other state

此解决方案基于您的规范:因此每个州将包含其json的新副本,并且不包含任何其他状态

You can use Newtonsoft json serializer to deserialize json create new instance for every state and serialize them back to json

您可以使用Newtonsoft json序列化程序反序列化json为每个状态创建新实例并将它们序列化回json

public class States
{
    public string Country { get; set; }
    public List<string> States { get; set; }        
}

public IEnumerable<string> GenerateSeparatedListOfStates(string json)
{
    var original = JsonConvert.DeserializaeObject<States>(json);

    foreach(string state in original.States)
    {
        var temp = new States 
        { 
            Country = state.Country,
            States = new List<string> { state }
        }
        yield return JsonConvert.SerializeObject(temp);
    }
}

#2


1  

You need deserialize your json into object, remove the object which you don't need from the States List and after that serialize it again.

您需要将json反序列化为对象,从States List中删除不需要的对象,然后再将其序列化。

    public class JsonClass
    {
        public string Country { get; set; }

        public List<string> States { get; set; }
    }


    static void Main(string[] args)
    {
        string json = @"{""Country"":""USA"",""States"":[""Chicago"",""Miami""]}";

        JsonClass className  = JsonConvert.DeserializeObject<JsonClass>(json);

        className.States.Remove("Miami");

        Console.WriteLine(JsonConvert.SerializeObject(className));

    }

Edit:

编辑:

About your question: remove all elements without Chicago:

关于你的问题:删除没有芝加哥的所有元素:

Change line:

换线:

className.States.Remove("Miami");

To:

至:

className.States.RemoveAll(x => x != "Chicago");

#3


1  

I've read all your question and all the comments to the other answers, and quite frankly I'm still unsure if this will answer what I think you are asking!

我已经阅读了你的所有问题以及对其他答案的所有评论,坦率地说,我仍然不确定这是否能回答我的想法!

This code does not require any external library, you simply need to add a reference to System.Web.Extensions to your project.

此代码不需要任何外部库,您只需要向项目添加对System.Web.Extensions的引用。

string jsonString = "{\"Country\":\"USA\",\"States\":[\"Chicago\",\"Miami\"]}";
var jss = new JavaScriptSerializer();
dynamic json = jss.DeserializeObject(jsonString);
var statesToRemove = new object[] { "Chicago", "Miami" };
object[] originalStates = json["States"] as object[];
foreach(var state in statesToRemove)
{
    json["States"] = new[] { state }; 
    string newJson = jss.Serialize(json);
}
// Outputs...
// {"Country":"USA","States":["Chicago"]}
// {"Country":"USA","States":["Miami"]}

We deserialize the json to an object graph and traverse it dynamically (using dynamic - this is how json["States"] even compiles). For each state in the statesToRemove collection, we serialize a new json string with that as the only state.

我们将json反序列化为对象图并动态遍历它(使用动态 - 这就是json [“States”]甚至编译的方式)。对于statesToRemove集合中的每个状态,我们将新的json字符串序列化为唯一的状态。

#4


1  

If you're just looking for a way to copy the JSON and replace the States array with just a single, known state, you could make your method like this:

如果你只是想找到一种方法来复制JSON并用一个已知的状态替换States数组,你可以像这样制作你的方法:

public static string Remove(string json, string stateToKeep)
{
    JObject jo = JObject.Parse(json);
    jo["States"] = new JArray(stateToKeep);
    return jo.ToString();
}

Fiddle: https://dotnetfiddle.net/hVz6yF

小提琴:https://dotnetfiddle.net/hVz6yF

If you're looking to do this for all the states in the States array without knowing in advance what they all are, you could do something like this instead:

如果你想在不知道它们都是什么的情况下为States数组中的所有状态执行此操作,则可以执行以下操作:

public static string Remove(string json)
{
    var obj = JObject.Parse(json);
    var result = obj["States"].Select(s =>
    {
        var clone = s.Root.DeepClone();
        clone["States"] = new JArray(s);
        return clone;
    });
    return new JArray(result).ToString();
}

Basically, we parse the JSON to a JObject, then iterate over the states using Select. For each state, we clone the entire JSON, then replace the clones' States array with a new JArray containing just the single state. Lastly, we put all these clones into a new JArray and convert it to string.

基本上,我们将JSON解析为JObject,然后使用Select迭代状态。对于每个状态,我们克隆整个JSON,然后用仅包含单个状态的新JArray替换克隆的States数组。最后,我们将所有这些克隆放入一个新的JArray并将其转换为字符串。

Given your original JSON, you would end up with this new result:

鉴于您的原始JSON,您最终会得到这个新结果:

[
  {
    "Country": "USA",
    "States": [
      "Chicago"
    ]
  },
  {
    "Country": "USA",
    "States": [
      "Miami"
    ]
  }
]

Fiddle: https://dotnetfiddle.net/qb4fu0

小提琴:https://dotnetfiddle.net/qb4fu0