来自多个 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你真的不能,但是你可以通过使用Where
和OfType
来简单地做到这一点:
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 中是不是为空