每个循环的 C# 2(如果一个循环有效,另一个循环不起作用)



我有两个不同的regex匹配,目前使用2个foreach循环来获取匹配值。然而,就目前而言,如果一个前臂有效,那么另一个就不行了。

尝试1个

foreach (string dir in multiTrimmed1)
{
foreach (string dir2 in multiTrimmed2)
{
var forVal2= dir.Replace("$", "").Replace(" ", "");
var forVal3 = dir2.Replace(",", "");
var parsedParams= new ParsedMethod()
{
Value1= forVal1,
Value2 = Convert.ToDecimal(forVal2),
Value3 = Convert.ToDecimal(forVal3),
Value4 = forVal4
};
MergeAllValues(parsedParams);
}
}

所以这里的问题是multiTrimmed1和multiTrimmed2分别有字符串[4]。

比方说A、B、C和D。在我的尝试1中,我希望forVal2和forVal3正确地通过循环。

我的意思是,当forVal2是A时,forVal3也是A-将其发送到MergeAllValues,next,B和B-将其发给MergeAllValue,next、C和C-将其送给MergeAllValues,nextD和D-将其寄给MergeAllalues。

目前只有一个循环有效。如果forVal3值变为A、B、C和D,则forVal2仅在A处停止。

尝试2

bool loopAgain = true;
while (loopAgain)
{
loopAgain = false;
foreach (string dir in multiTrimmed1)
{
foreach (string dir2 in multiTrimmed2)
{
var forVal2= dir.Replace("$", "").Replace(" ", "");
var forVal3 = dir2.Replace(",", "");
var parsedParams= new ParsedMethod()
{
Value1= forVal1,
Value2 = Convert.ToDecimal(forVal2),
Value3 = Convert.ToDecimal(forVal3),
Value4 = forVal4
};
MergeAllValues(parsedParams);
loopAgain = true;
break;
}
}

在这种情况下,forVal2得到的值很好,但forVal3保持在

尝试3

bool loopAgain = true;
while (loopAgain)
{
loopAgain = false;
foreach (string dir in multiTrimmed1)
{
var forVal2= dir.Replace("$", "").Replace(" ", "");

foreach (string dir2 in multiTrimmed2)
{
var forVal3 = dir2.Replace(",", "");
var parsedParams= new ParsedMethod()
{
Value1= forVal1,
Value2 = Convert.ToDecimal(forVal2),
Value3 = Convert.ToDecimal(forVal3),
Value4 = forVal4
};
MergeAllValues(parsedParams);
loopAgain = true;
break;
}
}

仍然只有工作循环有效。我怎样才能使两者都起作用?

您已经断言multiTrimmed1multiTrimmed2基于元素位置具有1:1的关系,因此我们可以使用.Zip:

foreach (var (dir, dir2) in multiTrimmed1.Zip(multiTrimmed2, (a,b) => (a, b)))
{
string forVal2 = dir.Replace("$", "").Replace(" ", "");
string forVal3 = dir2.Replace(",", "");
var parsedParams = new ParsedMethod()
{
Value1 = forVal1,
Value2 = Convert.ToDecimal(forVal2),
Value3 = Convert.ToDecimal(forVal3),
Value4 = forVal4
};
MergeAllValues(parsedParams);
}

在线试用

本质上,我们在这里所做的是同时循环通过multiTrimmed1multiTrimmed2,以在每个位置产生元素的ValueTuple(a来自multiTrimmed1b来自multiTrimmed2(。然后我们用var (dir, dir2)对其进行分解,这样我们就可以单独访问这些值。

上面的代码出现问题的原因是,对于List<T>或数组(T[](等具体集合,foreach每次都会从头开始。

所以当你写这样的东西时:

foreach (var a in colA)
{
foreach (var b in colB)
{
}
}

你在说"对于colA中的每个项目;(它本身恰好也包含一个循环。所以你不是同时循环两个集合,而是循环遍历外部集合(colA(,对于colA中的每个项目,你也要遍历colB中的每一个项目。

Zip的方法是从colA获取一个项,从colB获取一个项目,执行合并函数,然后生成值。然后,它从colA获取下一个项,从colB获取下一项并生成它们。这允许您同时有效地循环处理这两个集合。

因此,为了澄清它在内部的作用,您可以使用以下近似值来实现自己的Zip方法:

public static IEnumerable<T> MyZip<T, A, B>(IEnumerable<A> eA, IEnumerable<B> eB, Func<A, B, T> mergeFunc)
{
var aEnumerator = eA.GetEnumerator(); // get an enumerator for eA
var bEnumerator = eB.GetEnumerator(); // get an enumerator for eB
// while there are more items to be read in a AND b
while (aEnumerator.MoveNext() && bEnumerator.MoveNext())
{
// execute the mergeFunction on the value from a and the value from b and store the result
T itemResult = mergeFunc(aEnumerator.Current, bEnumerator.Current);
// return the result to the caller
yield return itemResult;
}
}

在线试用

最新更新