简体   繁体   中英

Find and remove elements from List<Dictionary<string, object>>

I'm currently working on a C# 4.7.2 application. I'm about to write an extension method for a custom type and I'm struggling with my LINQ query unfortunately.

I need filter a List<Dictionary<string, object>> to find the elements of Dictionary<string, object> in the list with a certain key and remove it from my list. Furthermore, a list entry can be null.

A list entry (dictionary) can look like this, there can be several elements with value key A, i need to remove all actually:

Key    |  Value
"MyId" : "A",
"Width" : 100,
"Length" : 50

Very simple structure. The tricky thing is to find the dictionary elements in the list. My extension method looks like that:

public static List<Dictionary<string, object>> RemoveItem(this List<Dictionary<string, object> items, string value)
{
    var itemToRemove = items.FirstOrDefault(x => x.ContainsKey("MyId")).Values.Contains(value);

    items.Remove(itemToRemove);

    return items;
}

Unfortunately this LINQ query does not work correctly.

Do you know how to solve this issue?

Thank you very much!!

You want to remove all with a key and a value? You don't even need LINQ:

public static int RemoveItems(this List<Dictionary<string, object>> dictionaryList, string value)
{
    int removed = dictionaryList
        .RemoveAll(dict => dict.TryGetValue("MyId", out object val) && value.Equals(val));
    return removed;
}

You could use the method RemoveAll of the list. Then you give in a predicate that checks the dictionary (which is a collection of KeyValuePair<TKey, TValue> ):

items.RemoveAll(dict => dict.Any(kv => kv.Key == "MyId" && ( kv.Value as string ) == "A"));

Or as suggested by Tim Schmelter :

items.RemoveAll(dict => dict.TryGetValue("MyId", out object value) && (value as string) == "A");

您将需要执行以下操作:

itemsToRemove = items.Where(x => x.ContainsKey("MyId") && x["MyId"].ToString() == value);

From your description, you seem to want the first dictionary containing the key with the value from the parameter value . That would be items.FirstOrDefault(x => x.ContainsKey(value))

What you are doing is getting dictionary containing one predefined key "myId" and then going through the objects inside the dictionary and comparing their values with your value parameter, which is not what you described you want.

If you expect more dictionaries to contain the given key,and you want to remove all of them, you should use list.RemoveAll(dict => dict.ContainsKey(value))

public static List<Dictionary<string, object>> RemoveItem(this List<Dictionary<string, object>> items, string value, string key)
{
    foreach (var item in items)
    {
        if(item.ContainsKey(key) && item[key] == value)
        {
            item.Remove(key);
        }
    }

    return items;
}

This gonna work just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM