c#2为每个循环,如果一个工作另一个不

c#

我有 2 个不同的正则表达式匹配项,目前使用 2 个 foreach 循环来获取匹配值。但是,就目前而言,如果一个 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 每个都有 string[4] 。

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

我的意思是,当 forVal2 是 A 时,forVal3 也是 A - 将其发送到 MergeAllValues,接下来,B 和 B - 将其发送到 MergeAllValues,接下来,C 和 C - 将其发送到 MergeAllValues,然后 D 和 D - 发送到 MergeAllValues。

目前只有一个循环有效。如果 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 保持在 A

尝试 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);
}

网上试试

本质上,我们在这里所做的是同时循环遍历multiTrimmed1并在每个位置(from和from )multiTrimmed2生成一个ValueTuple元素。然后我们将其分解,以便我们可以单独访问这些值。amultiTrimmed1bmultiTrimmed2var (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;
    }
}

网上试试


以上是c#2为每个循环,如果一个工作另一个不的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>