首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用递归从IDictionary中删除项

使用递归从IDictionary中删除项
EN

Stack Overflow用户
提问于 2008-10-24 22:16:30
回答 10查看 2.1K关注 0票数 3

有没有人有更巧妙的方法?看起来应该比这更容易,但我有一个心理障碍。基本上,我需要从字典中删除项,并递归到也是字典的项的值中。

代码语言:javascript
运行
复制
private void RemoveNotPermittedItems(ActionDictionary menu)
{
    var keysToRemove = new List<string>();
    foreach (var item in menu)
    {
        if (!GetIsPermitted(item.Value.Call))
        {
            keysToRemove.Add(item.Key);
        }
        else if (item.Value is ActionDictionary)
        {
            RemoveNotPermittedItems((ActionDictionary)item.Value);
            if (((ActionDictionary)item.Value).Count == 0)
            {
                keysToRemove.Add(item.Key);
            }
        }
    }
    foreach (var key in (from item in menu where keysToRemove.Contains(item.Key) select item.Key).ToArray())
    {
        menu.Remove(key);
    }
}

动作字典是这样的:

代码语言:javascript
运行
复制
public class ActionDictionary : Dictionary<string, IActionItem>, IActionItem
EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2008-10-25 06:17:27

如果您反向迭代字典(从'menu.Count - 1‘到0),那么您实际上不需要收集键并再次迭代它们。当然,如果你开始移除一些东西,以正向顺序迭代将会产生变异的集合异常。

我不知道什么是ActionDictionary,所以我无法测试您的确切场景,但这里有一个仅使用Dictionary<string,object>的示例。

代码语言:javascript
运行
复制
    static int counter = 0;
    private static void RemoveNotPermittedItems(Dictionary<string, object> menu)
    {
        for (int c = menu.Count - 1; c >= 0; c--)
        {
            var key = menu.Keys.ElementAt(c);
            var value = menu[key];
            if (value is Dictionary<string, object>)
            {
                RemoveNotPermittedItems((Dictionary<string, object>)value);
                if (((Dictionary<string, object>)value).Count == 0)
                {
                    menu.Remove(key);
                }
            }
            else if (!GetIsPermitted(value))
            {
                menu.Remove(key);
            }
        }
    }

    // This just added to actually cause some elements to be removed...
    private static bool GetIsPermitted(object value)
    {
        if (counter++ % 2 == 0)
            return false;
        return true;
    }

我还颠倒了'if‘语句,但这只是一个假设,假设'GetIsPermitted’总是为ActionDictionary返回TRUE,那么在调用一个方法对项的value...it执行操作之前,您需要进行类型检查。

希望这能有所帮助。

票数 3
EN

Stack Overflow用户

发布于 2008-10-24 22:24:23

首先,您的foreach循环比它需要的复杂得多。只需这样做:

代码语言:javascript
运行
复制
foreach (var key in keysToRemove)
{
    menu.Remove(key);
}

我对Dictionary没有RemoveAll方法感到有点惊讶,但它看起来并不像是……

票数 2
EN

Stack Overflow用户

发布于 2008-10-25 04:44:44

当foreach和GetEnumerator失败时,for循环可以工作,

代码语言:javascript
运行
复制
var table = new Dictionary<string, int>() {{"first", 1}, {"second", 2}};
for (int i = 0; i < table.Keys.Count; i++)//string key in table.Keys)
{
    string key = table.Keys.ElementAt(i);
    if (key.StartsWith("f"))
    {
        table.Remove(key);
    }
}

但是ElementAt()是.NET 3.5的一个特性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/235446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档