【问题标题】:List<String> not removing item [closed]List<String> 不删除项目 [关闭]
【发布时间】:2011-07-31 22:52:04
【问题描述】:

我正在编写一个呼叫跟踪应用程序,它访问一个推送服务器并获取传入呼叫的​​ JSON 结果集。在 JSON 对象中,有一个包含每个呼叫的 logID 的键数组。

当一个新的调用进来时,我创建一个新的标签页并将一个调用对象与标签页标签属性相关联。然后我检查是否已处理调用,如果它有推送服务器从 Keys 数组中删除 logID。然后我将 Keys 数组中的 logIds 与每个调用对象的 logIds 进行比较,这与每个打开的选项卡相关联。

运行我的代码时,它会从 _psKeys 列表中删除 logID,然后在下一次迭代中将其添加回来。谁能告诉我我做错了什么。

        var jsonResult = _pushServer.GetWebRequest(_pushServer.GetNewCallUrl(_locationID, _clientID));
        var jsonObject = _pushServer.GetJsonObject(jsonResult);

        _tabKeys.Clear();
        _psKeys.Clear();

        // Load the tabKeys with all the keys for the open tabs.
        foreach (TabPage tab in newCallTabControl.TabPages)
        {
            Call call = (Call)tab.Tag;
            _tabKeys.Add(call.LogID);                
        }

        // Load the Push Server Keys
        foreach (string key in jsonObject.keys)
        {
            _psKeys.Add(key);                
        }

        // Iterate over the keys and compare
        foreach (string tabKey in _tabKeys)
        {
            foreach (string psKey in _psKeys)
            {
                if (! _tabKeys.Contains(psKey))
                {
                    // Remove the tab
                    foreach (TabPage tabPage in newCallTabControl.TabPages)
                    {
                        Call tabCallObject = (Call)tabPage.Tag;
                        if (tabCallObject.LogID == tabKey)
                        {
                            newCallTabControl.TabPages.Remove(tabPage);                        
                        }
                    }
                }                    
            }                
        }

【问题讨论】:

  • 这在codereview stackexchange上会更好

标签: c# json list


【解决方案1】:

您不应该从正在枚举的列表中删除项目。我根本不会一开始就添加它们....

    var jsonResult = _pushServer.GetWebRequest(_pushServer.GetNewCallUrl(_locationID, _clientID));
    var jsonObject = _pushServer.GetJsonObject(jsonResult);

    _tabKeys.Clear();
    _psKeys.Clear();
// Load the Push Server Keys
    foreach (string key in jsonObject.keys)
    {
        _psKeys.Add(key);                
    }
    var tabsToRemove = new List<TabPage>();
// Load the tabKeys with all the keys for the open tabs.
    foreach (TabPage tab in newCallTabControl.TabPages)
    {
        Call call = (Call)tab.Tag;
        if(_psKeys.Contains(call.LogID)
        {               
          _tabKeys.Add(call.LogID); 
        }               
        else
        {
          tabsToRemove.Add(tab)
        }
    }
    tabsToRemove.ForEach(t => newCallTabControl.TabPages.Remove(t));

或者如果您不需要这些列表...

var tabsToRemove = newCallTabControl.TabPages
          .Where(tab => !jsonObject.keys.Contains(((Call)tab.tag).LogID))
          .ToList();
tabsToRemove.ForEach(t => newCallTabControl.TabPages.Remove(t)); 

【讨论】:

  • 我应该用什么来保存 logId 并比较它们?数组会是更好的选择吗?
  • 即使我删除了从 _tabKeys 列表中删除项目的行,该列表也会被清除并从 JSON 结果中自动填充,并提供相同的结果。
  • 我只是稍微编辑了一下。很难从上下文中知道发生了什么。对我来说似乎有点令人费解
  • 你摇滚!谢谢那个像魅力一样工作的人......只需要在 if 语句之外创建 Call 对象。
  • 我喜欢第二个选项,但它不起作用。 TabPage 上没有 Where 方法?
【解决方案2】:

你可以使用Linq获取你需要操作的数据,然后分别进行操作:

var tabKeysToRemove = _tabKeys.Where(t => !_psKeys.Contains(t)).ToList();
foreach (var tabKey in tabKeysToRemove)
{
    _tabKeys.Remove(tabKey);
    var tabsToRemove = newCallTabControl.TabPages
        .Where(tp => ((Call)tp.Tag).logID == tabKey).ToList();
    tabsToRemove.forEach(t => newCallTabControl.TabPages.Remove(t));
}

【讨论】:

  • 这不会按原样工作。由于 LINQ 的惰性,当您从中删除项目时,您仍在迭代 _tabKeys。您需要在每个 LINQ 链的末尾调用 .ToList() 以将删除列表与原始列表分离。
  • @Andrew - 谢谢,很高兴知道。我更新了我的答案。
【解决方案3】:

您正在修改您正在迭代的几个集合。这绝不是一个好主意。

此外,就循环的逻辑而言,您似乎没有对 _psKeys 上的迭代做任何事情。应该是这样的:

foreach (string tabKey in _tabKeys)        
{            
    if (! _psKeys.Contains(tabKey))
    {
        //Remove the tab
        //...
    }
}

【讨论】:

    猜你喜欢
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    相关资源
    最近更新 更多