ForEach循环从List / Collection的Middle / Anywhere开始,然后遍历所有项目

时间:2018-03-07 09:55:34

标签: c# wpf

我需要在多级树视图中从当前所选项目中搜索列表中的内容。我的树视图中有4个级别,并且在第4级搜索符合某些条件的节点。查看下面的图像: enter image description here

现在在这张图片中我正在搜索里面有1个的红色块(失败一个)。以下是我要搜索的代码:

foreach (var Project in Projects)
{
    foreach (var Devices in Project.TestRuns)
    {
        foreach (var Category in Devices.TestModuleCategories)
        {
            foreach (var TestModule in Category.TestModules)
            {
                foreach (var statement in TestModule.TestModuleStatementList)
                {
                    if (statement.TestsFailed == 1 && !statement.IsSearched)
                    {
                        TestModule.TestModuleStatementList.ForEach(f => { f.IsCurrentFocused = false; });
                        statement.IsCurrentFocused = true;
                        statement.IsSearched = true;
                        TreeViewItem item = GetTreeViewItem(ViewTestDataTree, statement);
                        item.IsExpanded = true;
                        //ViewTestData.SetSelectedItem(ref ViewTestDataTree, item);
                        //item.Focus();
                        return;
                    }
                    statement.IsCurrentFocused = false;
                }

            }
        }
    }
}

Projects.ForEach(a => a.TestRuns.ForEach(b => b.TestModuleCategories.ForEach(c => c.TestModules.ForEach(d => d.TestModuleStatementList.ForEach(f => { f.IsSearched = false; })))));

现在的问题是我每次搜索时都会运行foreach循环,但我希望如果用户位于列表的中间位置,那么搜索应该从列表的最后一个开始,并从顶部开始保留列表。是否有任何机制可以从集合中的任何位置启动并从下到上搜索所有节点?

3 个答案:

答案 0 :(得分:2)

我建议将foreach循环封装在一个返回搜索结果的IEnumerable实例的方法中:

IEnumerable<Statement> Search(/* put parameters here*/)
{
     Foreach(...)
         Foreach(...)
            Foreach(...)
              Foreach(...)
              {
                  if(...)
                     yield return statement;
              }
}

在主搜索管理中,保留IEnumerator对象的实例,以便直接切换到下一个搜索结果:

 IEnumerator<Statement> searchResults;
 void NextResult()
 {
     if (searchResults == null)
         searchResults = Search( /* parameters...*/).GetEnumerator();

      if (!searchResults.MoveNext())
     {
         // In this situation we have reached the end of the tree
         // Restart from the beginning
         searchResults.Reset();
         searchResults.MoveNext();
     }

     var statement = searchResults.Current;
     if (statement != null)
     {
         // ...
         // Actions regarding current statement
         // ...
     }
 }

当然,应该调整解决方案以考虑搜索条件的变化。

答案 1 :(得分:1)

对于每个循环都不提供索引访问(它只保存指向当前项和集合中下一项的指针),因此它将每次从头开始。

答案 2 :(得分:1)

您可以创建另一个列表来展平树:

int selectedIndex = statements.FindIndex(f => f.IsCurrentFocussed);
int searchPos = (selectedIndex + 1) % statements.Count;
while (searchPos != selectedIndex)
{
    if (statement.TestsFailed == 1 && !statement.IsSearched)
    {
        statements.ForEach(f => { f.IsCurrentFocused = false; });
        statement.IsCurrentFocused = true;
        statement.IsSearched = true;
        TreeViewItem item = GetTreeViewItem(ViewTestDataTree, statement);
        item.IsExpanded = true;
        return;
    }
    searchPos = (selectedIndex + 1) % statements.Count;
}

然后你可以使用一个while循环,它将从当前位置+ 1开始并回绕开始并在当前位置之前结束:

<ng2-datepicker [options]="options" [(ngModel)]="date" [disabled]="fourthdrpdwn"></ng2-datepicker>