来自多个 Foreach 的 Linq

Posted

技术标签:

【中文标题】来自多个 Foreach 的 Linq【英文标题】:Linq from multiple Foreach 【发布时间】:2018-08-28 01:38:02 【问题描述】:

如何将以下多个foreach 转换为 LINQ?

    foreach (var resourceOne in resourceList)
    
        string s = (string)resourceOne;
        foreach (Control c in gridBtn.Children)
        
            if (c.GetType() == typeof(ToggleButton))
            
                int TagPlusOne = Convert.ToInt32(c.Tag) + 1;
                string PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
                if (PaddedResult == s)
                
                    ((ToggleButton)c).BorderBrush = Brushes.Red;
                    ((ToggleButton)c).BorderThickness = new Thickness(3, 3, 3, 3);
                
            
        
     

【问题讨论】:

【参考方案1】:
IEnumerable<ToggleButton> query =
  from c in gridBtn.Children
  where c.GetType() == typeof(ToggleButton)
  let tagPlusOne = Convert.ToInt32(c.Tag) + 1
  let paddedResult = tagPlusOne.ToString().PadLeft(3, '0')
  join s in resourceList.Cast<string>() on paddedResult equals s
  select c;


foreach(ToggleButton button in query)

  button.BorderBrush = Brushes.Red;
  button.BorderThickness = new Thickness(3, 3, 3, 3);

【讨论】:

被赞为更符合问题的精神 好吧,这实际上好多了 关于以下错误的任何想法:找不到源类型“UIElement Collection”的查询模式的任何实现。找不到。 gridBtn 实际上它是我的 wpf 网格控件 如果 gridBtn.Children 没有实现 IEnumerable,你可以调用 OfType【参考方案2】:

你真的不能,但是你可以通过使用WhereOfType来简单地做到这一点:

foreach (var in gridBtn.Children.OfType<ToggleButton>)

    int TagPlusOne = Convert.ToInt32(c.Tag) + 1;
    string PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
    foreach (var resourceOne in resourceList.Where(x => x == PaddedResult))
    
        c.BorderBrush = Brushes.Red;
        c.BorderThickness = new Thickness(3, 3, 3, 3);
    

免责声明:完全未经测试。

【讨论】:

【参考方案3】:

最后,您需要foreach 或类似名称来设置按钮的属性,因为 LINQ 用于查询您的数据(通常无副作用),而不是改变它们。但是,您可以使用 LINQ 来简化查找要编辑的按钮。例如您的代码可以归结为:

var targetButtons = gridBtn
    .Children
    .OfType<ToggleButton>()
    .Where(tb => resourceList.OfType<string>().Contains($"Convert.ToInt32(tb.Tag) + 1:D3"));

foreach(var btn in targetButtons)

    btn.BorderBrush = Brushes.Red;
    btn.BorderThickness = new Thickness(3, 3, 3, 3);

可以进一步调整/优化/重构。请注意,我已将 PadLeft(3, '0') 替换为具有相同作用的 D3 标准数字格式字符串。

【讨论】:

不知何故 $"Convert.ToInt32(tb.Tag) + 1:D3") 不适用于我的 WPF 。由于 $ 无法识别。我使用我的原始代码 padleft 并且它可以工作。谢谢 @LohZhiCheng $"..." 是一个interpolated string,类似于string.Format。这是 C# 6 的特性。如果它不可用,那么您可能使用的是旧版本的 C#。【参考方案4】:

你可以做这样的事情(虽然我无法测试它,因为我没有你的环境):

gridBtn.Children.Where(c =>
        c.GetType() == typeof(ToggleButton) && resourceList.Any(resourceOne =>
            (string) resourceOne ==
            Convert.ToInt32(c.Tag) + 1.ToString().PadLeft(3, '0')))
    .ToList().ForEach(c =>
    
        ((ToggleButton) c).BorderBrush = Brushes.Red;
        ((ToggleButton) c).BorderThickness = new Thickness(3, 3, 3, 3);
    );

【讨论】:

【参考方案5】:

您可以使用此代码。我为按钮和 WinForm 测试了这样的代码。 我希望代码对您有所帮助。

resourceList.Where(resourceOne =>
        
            string s = (string)resourceOne;
            gridBtn.Children.OfType<ToggleButton>().Where(c =>
            
                var TagPlusOne = Convert.ToInt32(c.Tag) + 1;
                var PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
                return PaddedResult == s;
            ).ToList().ForEach(c =>
            
                c.BorderBrush = Brushes.Red;
                c.BorderThickness = new Thickness(3, 3, 3, 3);
            );
            return true;
        );

我认为您也可以使用 Select 而不是 Foreach。

esourceList.Where(resourceOne =>
        
            string s = (string)resourceOne;
            var enumerable = ActiveForm.Controls.OfType<Button>().Where(control =>
            
                var TagPlusOne = Convert.ToInt32(control.Tag) + 1;
                var PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
                return PaddedResult == s;
            ).Select(control =>
            
                control.BackColor = Color.Aqua;
                control.Cursor = Cursors.WaitCursor;
                return control;
            );
            return true;
        );

【讨论】:

谢谢我已经用简化的代码找到了上面的可行答案。再次感谢

以上是关于来自多个 Foreach 的 Linq的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS - 控制器 - 来自集合的多个查询 + forEach

PHP Mysql PDO查询来自foreach存储的多个值以供输出

ForEach 通过多个 TextField 来验证 SwiftUI 中是不是为空

codeigniter foreach 具有相同 ID 的多个条目,对元素求和并显示为一个

来自mongodb的多个集合的总和

TSQL 多个连接与来自 ASP.NET Core 的多个请求?