【问题标题】:How to overcome foreach loop for list object dynamically如何动态克服列表对象的foreach循环
【发布时间】:2019-10-08 12:23:24
【问题描述】:

我在某些条件下交换列表对象中的值并更新列表对象值。

目前,我正在做的是 - 通过列表循环每个对象 - 检查条件是否为净 - 交换值

public static void SwapMinMaxIfNull<T>(this IEnumerable<T> rows, string reportfor)
{
   if (reportfor.Equals("Comparison"))
   {
      var row = rows as IEnumerable<RiskBoardDataToExport>;                
      try
      {
         if (rows.Any())
         {
            var Tests = row.Where(min => min.MinGaitSpeed == null && min.MaxGaitSpeed != null).ToList();
            if (Tests != null)
            {
               foreach (RiskBoardDataToExport test in Tests)
               {
                  test.MinGaitSpeed = test.MaxGaitSpeed;
                  test.MaxGaitSpeed = null;
               }
            }
            // again check for next object 
            Tests = row.Where(min => min.MinTUGTime == null && min.MaxTUGTime != null).ToList();
            if (Tests != null)
            {
               foreach (RiskBoardDataToExport test in Tests)
               {
                  test.MinTUGTime = test.MaxTUGTime;
                  test.MaxTUGTime = null;
               }
            }
            // again check for next object
             Tests = row.Where(min => min.MinBergScoreSpeed == null && min.MaxBergScoreSpeed != null).ToList();
             if (Tests != null)
             {
                foreach (RiskBoardDataToExport test in Tests)
                {
                   test.MinBergScoreSpeed = test.MaxBergScoreSpeed;
                   test.MaxBergScoreSpeed = null;
                }
             }
             //.. for brevity
          }
     }
}

我能以更好的方式做到这一点吗?我知道 PropertyInfo 即可以检查属性名称并获取值等,但是没有任何提示可以完成此操作。

谢谢

【问题讨论】:

  • 首先,您不必对您的 Lambada 表达式执行 .ToList()。如果我理解正确,您想更新符合特定条件的对象的属性值吗?如果这是您想要的,那么可能想看看this 或者我错过了什么?
  • 你做一个泛型,在方法内部你做一个特定类型的转换,考虑给泛型添加一个限制,这样你的方法只能用这些类型调用
  • 是的,如果T 始终是RiskBoardDataToExport,则使用它来代替。
  • @CoderofCode 我需要 where 子句是动态的,即只给出源和目标并实现我想要的。但是,仍然没有任何线索。我只想一次又一次地摆脱foreach
  • 另外,Where 不会返回 null 值,因此您可以摆脱所有 if (Tests != null) 块。

标签: c# .net list object dynamic


【解决方案1】:

这并不完全符合您的要求,但您可以将 Where 语句中的子句组合起来,然后在正文中添加一些 if 语句:

public static void SwapMinMaxIfNull(this IEnumerable<RiskBoardDataToExport> rows, 
    string reportfor)
{
    if (rows = null) return;

    if (reportfor.Equals("Comparison", StringComparison.OrdinalIgnoreCase))
    {
        foreach (var row in rows.Where(r =>
            (r.MinGaitSpeed == null && r.MaxGaitSpeed != null) ||
            (r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null) ||
            (r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null)))
        {
            if (row.MinGaitSpeed == null)
            {
                row.MinGaitSpeed = row.MaxGaitSpeed;
                row.MaxGaitSpeed = null;
            }
            if (row.MinTUGTime == null)
            {
                row.MinTUGTime = row.MaxTUGTime;
                row.MaxTUGTime = null;
            }
            if (row.MinBergScoreSpeed == null)
            {
                row.MinBergScoreSpeed = row.MaxBergScoreSpeed;
                row.MaxBergScoreSpeed = null;
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    由于这是一项操作,列表中项目的顺序无关紧要,您可以通过并行化轻松加快此操作(您可以阅读here)。

    所以,你应该做的是,以并行方式处理这个 foreach 循环,并将它与 Rufus L 的优化代码结合起来,以获得最快的结果。

    var rows = rows.Where(r =>
       (r.MinGaitSpeed == null && r.MaxGaitSpeed != null) ||
       (r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null) ||
       (r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null))
    
    Parallel.ForEach(rows, (row) => {
    {
       if (row.MinGaitSpeed == null)
       {
          row.MinGaitSpeed = row.MaxGaitSpeed;
          row.MaxGaitSpeed = null;
       }
       if (row.MinTUGTime == null)
       {
          row.MinTUGTime = row.MaxTUGTime;
          row.MaxTUGTime = null;
       }
       if (row.MinBergScoreSpeed == null)
       {
          row.MinBergScoreSpeed = row.MaxBergScoreSpeed;
          row.MaxBergScoreSpeed = null;
       }
    }
    

    请注意,这需要 System.Threading.Tasks 命名空间,这就是 Parallel 类所在的位置。

    【讨论】:

    • 这会影响数据丢失
    猜你喜欢
    • 2020-01-01
    • 2015-05-06
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 2017-01-23
    • 2021-10-05
    相关资源
    最近更新 更多