【问题标题】:Foreach performs reduntant logicForeach 执行冗余逻辑
【发布时间】:2017-03-24 23:25:36
【问题描述】:

我的两个 ForEach 循环允许访问 errorOrders(用户名及其错误数)和 totalOrders(用户名及其总订单数)。

我的代码不断循环通过这两个 ForEache。 errorOrderstotalOrders 的“计数”都是 38,程序循环遍历所有 38 个用户就好了。但随后它会一次又一次地循环遍历它们,重新执行刚刚完成的过程。

我怎样才能只循环一次用户?

foreach (KeyValuePair<string, int> error in errorOrders)
{
    foreach (KeyValuePair<string, int> total in totalOrders)
    {

        errPercentage = ((double)error.Value / (double)total.Value);                        
        Console.WriteLine("Percentage of errors for " + total.Key + ": " + Math.Round(errPercentage, 2) * 100 + "%");
        ordersPerHour = OrdersPerHour(total.Key);
        RandomOrders = RandomSelect(errPercentage, total.Key);

        Console.WriteLine("Number of orders pulled : " + RandomOrders.Rows.Count);
        //Print out orders randomly collected
        for (int i = 0; i < RandomOrders.Rows.Count; i++) 
        {
            Console.WriteLine(RandomOrders.Rows[i]["ControlNumber"]);
        }

        Console.WriteLine("\r\n");
        //NumOrdersToPull = FindNumOrdersToPull(Math.Round(errPercentage,2), ordersPerHour);
    }

}

【问题讨论】:

  • 你真的需要遍历 totalOrders for each 错误吗?另外,根据您写的描述,似乎每个订单都有错误。
  • 为什么要使用嵌套循环?我会想象 errorOrders 会小于 totalOrders 并且您不希望在每个错误消息上循环通过 totalOrders。
  • 你说这个循环覆盖用户......在哪里?我在这段代码中没有看到任何关于用户的信息。另外,什么是 RandomSelect 和 RandomOrders?

标签: c# foreach keyvaluepair


【解决方案1】:

分离循环而不是嵌套循环。将一个放在另一个里面会使 整个 子循环运行 for each 父循环的实例。 (因此得名。)

// (shared variables here)

foreach (KeyValuePair<string, int> total in totalOrders)
{
    // Code relevant to all orders here
}

foreach (KeyValuePair<string, int> error in errorOrders)
{
    // Code relevant to erroneous orders only here
}

如果循环需要共享变量,请在第一个循环之前声明它们。在循环中创建的变量将是本地的,并且在它们的循环结束时停止存在。

【讨论】:

  • 他在循环中同时使用了 totalOrders 和 errorOrders:errPercentage = ((double)error.Value / (double)total.Value);
  • @Tejo,没错,OP 可能需要交换循环的顺序。如果 totalOrders 和 errorOrders 都相关,则需要在循环之外声明它们,以便在一个 foreach 完成时不会销毁它们。
  • 如果我将 totalOrders 和 errorOrders 分成两个不同的循环,你会如何建议我获得 errPercentage?
  • @MaylorTaylor 如果你的 totalOrders 循环出现在 errorOrders 之前,你需要在第一个循环之前声明一个变量来保存(double)total.Value。通过将其存储在循环之外,当您深入到第二个循环时,您仍然可以访问该变量。
【解决方案2】:

第二个循环将针对总订单中的每个总数运行一次。如果您希望它们只经过一次,请不要嵌套它们。而是一个接一个。

foreach(total in total orders)
{

}
foreach(error in errororders)
{

}

如果它们是相关的,您只需要嵌套它们,并且您需要为外部循环的每次迭代执行一次内部循环。

【讨论】:

    【解决方案3】:

    试试这个:

    foreach (KeyValuePair<string, int> error in errorOrders)
    {
        if (totalOrder.HasKey(error.Key) {
            var total = totalOrders[error.Key];
    
            errPercentage = ((double)error.Value / (double)total);                        
            Console.WriteLine("Percentage of errors for " + error.Key + ": " + Math.Round(errPercentage, 2) * 100 + "%");
            ordersPerHour = OrdersPerHour(error.Key);
            RandomOrders = RandomSelect(errPercentage, error.Key);
    
    
            Console.WriteLine("Number of orders pulled : " + RandomOrders.Rows.Count);
            //Print out orders randomly collected
            for (int i = 0; i < RandomOrders.Rows.Count; i++) 
            {
                Console.WriteLine(RandomOrders.Rows[i]["ControlNumber"]);
            }
    
            Console.WriteLine("\r\n");
            //NumOrdersToPull = FindNumOrdersToPull(Math.Round(errPercentage,2), ordersPerHour);
        }
    }
    

    【讨论】:

      【解决方案4】:

      或者甚至只是一个循环,然后查找另一个? totalOrders 是某种列表吗?如果你可以把一个变成字典,你可以做类似的事情

      foreach (KeyValuePair<string, int> total in totalOrders)
      {
          // do work for each order
          object whatever;
          if (errorOrders.TryGetValue( total.Key, out whatever ))
          {
              // do extra work because this order has an error
          }
      }
      

      【讨论】:

        【解决方案5】:

        其他答案帮助我得出了这个结论:

        foreach (KeyValuePair<string, int> e in errorOrders)
        {
            errPercentage = GetErrPercentage(e.Key);
            Console.WriteLine("Percentage of errors for " + e.Key + ": " + Math.Round(errPercentage, 2) * 100 + "%");
            ordersPerHour = OrdersPerHour(e.Key);
            RandomOrders = RandomSelect(errPercentage, e.Key);
        }
        
        Console.WriteLine("Number of orders pulled : " + RandomOrders.Rows.Count);
        //Print out orders randomly collected
        for (int i = 0; i < RandomOrders.Rows.Count; i++)
        {
            Console.WriteLine(RandomOrders.Rows[i]["ControlNumber"]);
        }
        Console.WriteLine("\r\n");
        
        static double GetErrPercentage(string user)
        {
            double errPercentage = 0;
            errPercentage = (double)errorOrders[user]/ (double)totalOrders[user];          
            return errPercentage;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-29
          • 2016-03-21
          • 2017-06-21
          相关资源
          最近更新 更多