给定代码的优化版本是什么?

发布于 2024-10-18 07:39:56 字数 372 浏览 2 评论 0原文

我有一段代码,我在其中检查复选框,比较给定代码中数据表的内容:

 foreach (DataRow dr in dtResult.Rows)
 {
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
      if (chkboxListWorkTypes.Items[i].Value.Equals(dr["WorkTypeID"].ToString()))
      {
         chkboxListWorkTypes.Items[i].Selected = true;
      }
    }
 }

任何 labmda 或 linq 表达式都很棒。

I have a block of code where i am checking checkboxes, comparing the contents of the datatable in the given code:

 foreach (DataRow dr in dtResult.Rows)
 {
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
      if (chkboxListWorkTypes.Items[i].Value.Equals(dr["WorkTypeID"].ToString()))
      {
         chkboxListWorkTypes.Items[i].Selected = true;
      }
    }
 }

Any labmda or linq expression would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

刘备忘录 2024-10-25 07:39:56

真正的优化将是数据绑定。

Real optimization will be a data binding.

断念 2024-10-25 07:39:56

我就会这样做,

 foreach (DataRow dr in dtResult.Rows)
 {
    string cWorkTypeID = dr["WorkTypeID"].ToString();
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
         if(chkboxListWorkTypes.Items[i].Value.Equals(cWorkTypeID))
           chkboxListWorkTypes.Items[i].Selected =true;
    }
 }

如果复选框上的 ID 不同(可能是不同),

 foreach (DataRow dr in dtResult.Rows)
 {
    string cWorkTypeID = dr["WorkTypeID"].ToString();
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
         if(chkboxListWorkTypes.Items[i].Value.Equals(cWorkTypeID))
         {
            chkboxListWorkTypes.Items[i].Selected = true;
            break;
         }
    }
 }

This is what I do

 foreach (DataRow dr in dtResult.Rows)
 {
    string cWorkTypeID = dr["WorkTypeID"].ToString();
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
         if(chkboxListWorkTypes.Items[i].Value.Equals(cWorkTypeID))
           chkboxListWorkTypes.Items[i].Selected =true;
    }
 }

if the ID on the checkboxes is diferent (that probably is),

 foreach (DataRow dr in dtResult.Rows)
 {
    string cWorkTypeID = dr["WorkTypeID"].ToString();
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
         if(chkboxListWorkTypes.Items[i].Value.Equals(cWorkTypeID))
         {
            chkboxListWorkTypes.Items[i].Selected = true;
            break;
         }
    }
 }
触ぅ动初心 2024-10-25 07:39:56

尽管它在幕后的作用与 @Aristos 的回答几乎相同,但按以下方式执行会减少代码行数:

foreach (DataRow dr in dtResult.Rows)
{
    ListItem item = chkboxListWorkTypes.Items.FindByValue(dr["WorkTypeID"].ToString());
    if (item != null)
    {
         item.Selected = true;
    }
}

Though it does practically the same thing behind the scenes as @Aristos answer, doing it like the following will cut your lines of code down a bit:

foreach (DataRow dr in dtResult.Rows)
{
    ListItem item = chkboxListWorkTypes.Items.FindByValue(dr["WorkTypeID"].ToString());
    if (item != null)
    {
         item.Selected = true;
    }
}
请恋爱 2024-10-25 07:39:56

您本质上是在执行 JOIN 操作。有 3 种类型常用的连接算法 - 嵌套循环、散列和合并。您的代码正在使用嵌套循环算法 - 这似乎适合 10 和 5 的表大小,除非其中一个或两个已经排序(在这种情况下,合并联接可能更合适)。

我无法想象这会成为任何现实应用程序中的瓶颈 - 但是,我们可以通过一些假设对其进行一些改进。

  1. 让我们从提升变量开始,以确保它们不会被重新计算(JIT 优化器可能会自动执行此操作,但这并没有什么坏处):
    <前><代码>
    int chkBoxCount = chkboxListWorkTypes.Items.Count;
    foreach(dtResult.Rows 中的 DataRow dr)
    {
    字符串 rowValue = dr["WorkTypeID"].ToString();
    for (var i = 0; i < chkBoxCount; i++)
    {
    var chkBox = chkboxListWorkTypes.Items[i];
    if (chkBox.Value.Equals(rowValue))
    {
    chkBox.Selected = true;
    }
    }
    }
  2. 假设 rowValue 是一个字符串,让我们使用强制转换:
    <前><代码>
    int chkBoxCount = chkboxListWorkTypes.Items.Count;
    foreach(dtResult.Rows 中的 DataRow dr)
    {
    字符串 rowValue = (字符串)dr["WorkTypeID"];
    for (var i = 0; i < chkBoxCount; i++)
    {
    var chkBox = chkboxListWorkTypes.Items[i];
    if (chkBox.Value.Equals(rowValue))
    {
    chkBox.Selected = true;
    }
    }
    }
  3. 由于我们永远不会取消选中复选框,因此布尔比较平均应该比字符串比较更快:
    <前><代码>
    int chkBoxCount = chkboxListWorkTypes.Items.Count;
    foreach(dtResult.Rows 中的 DataRow dr)
    {
    字符串 rowValue = (字符串)dr["WorkTypeID"];
    for (var i = 0; i < chkBoxCount; i++)
    {
    var chkBox = chkboxListWorkTypes.Items[i];
    if (!chkBox.Selected && chkBox.Value.Equals(rowValue))
    {
    chkBox.Selected = true;
    }
    }
    }
  4. 假设每个复选框值都是唯一的,我们可以在找到结果时停止迭代:
    <前><代码>
    int chkBoxCount = chkboxListWorkTypes.Items.Count;
    foreach(dtResult.Rows 中的 DataRow dr)
    {
    字符串 rowValue = (字符串)dr["WorkTypeID"];
    for (var i = 0; i < chkBoxCount; i++)
    {
    var chkBox = chkboxListWorkTypes.Items[i];
    if (!chkBox.Selected && chkBox.Value.Equals(rowValue))
    {
    chkBox.Selected = true;
    休息; // 停止寻找
    }
    }
    }
  5. 由于您有 10 行和 5 个复选框 - 我们应该反转循环。由于我们在找到值时中断内部循环,因此使内部循环成为 2 中较大的一个会更有效:
    <前><代码>
    int chkBoxCount = chkboxListWorkTypes.Items.Count;
    for (var i = 0; i < chkBoxCount; i++)
    {
    var chkBox = chkboxListWorkTypes.Items[i];
    if (chkBox.Selected) 继续;
    foreach(dtResult.Rows 中的 DataRow dr)
    {
    字符串 rowValue = (字符串)dr["WorkTypeID"];
    if (chkBox.Value.Equals(rowValue))
    {
    chkBox.Selected = true;
    休息;
    }
    }
    }
  6. 假设您不关心文化或区分大小写的比较,我们可以使用 OrdinalIgnoreCase:
    <前><代码>
    int chkBoxCount = chkboxListWorkTypes.Items.Count;
    for (var i = 0; i < chkBoxCount; i++)
    {
    var chkBox = chkboxListWorkTypes.Items[i];
    if (chkBox.Selected) 继续;
    foreach(dtResult.Rows 中的 DataRow dr)
    {
    字符串 rowValue = (字符串)dr["WorkTypeID"];
    if (string.Equals(chkBox.Value, rowValue, StringComparison.OrdinalIgnoreCase))
    {
    chkBox.Selected = true;
    休息;
    }
    }
    }

这就是我能做的最好的事情了。如果在如此小的数据集上存在任何可测量的差异,我会感到惊讶。所以,这就是你真正应该做的:

 var workTypeIds = dtResult.Rows.Cast<DataRow>().Select(dr => (string)dr["WorkTypeId"]);
 foreach (var chk in chkBoxListWorkTypes) 
 {
     if (workTypeIds.Contains(chk.Value))
     {
        chk.Selected = true;
     }
 }    

或者,使用 Each 扩展:

 var workTypeIds = dtResult.Rows.Cast<DataRow>().Select(dr => (string)dr["WorkTypeId"]);
 chkBoxListWorkTypes.Where(c => workTypeIds.Contains(c.Value)).Each(c => c.Selected = true);

这可能会稍微慢一些,但在我看来读起来要好得多。

You're essentially performing a JOIN operation. There are 3 types of join algorithms in common use - nested loop, hash, and merge. Your code is using the nested loop algorithm - which seems appropriate for table sizes of 10 and 5, unless one or both are already sorted (in which case, a merge join may be more appropriate).

I can't imagine this being a bottleneck in any real-world application - but, we can possibly improve it a little bit with some assumptions.

  1. Let's start by hoisting variables, to ensure they're not being recalculated (the JIT-optimizer will probably do this automatically, but it doesn't hurt):
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = dr["WorkTypeID"].ToString();
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (chkBox.Value.Equals(rowValue))
          {
             chkBox.Selected = true;
          }
        }
     }
    

  2. On the assumption that rowValue is a string, let's use a cast:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = (string)dr["WorkTypeID"];
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (chkBox.Value.Equals(rowValue))
          {
             chkBox.Selected = true;
          }
        }
     }
    

  3. Since we're never unselecting a checkbox, and a bool compare should be faster on average than a string compare:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = (string)dr["WorkTypeID"];
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (!chkBox.Selected && chkBox.Value.Equals(rowValue)) 
          {
             chkBox.Selected = true;
          }
        }
     }
    

  4. Assuming each checkbox value is unique, we can stop iterating when we've found a result:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = (string)dr["WorkTypeID"];
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (!chkBox.Selected && chkBox.Value.Equals(rowValue)) 
          {
             chkBox.Selected = true;
             break; // stop looking
          }
        }
     }
    

  5. Since you have 10 rows, and 5 checkboxes - we should reverse the loops. Since we break on the inner loop when value is found, making the inner loop the larger of the 2 is more efficient:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     for (var i = 0; i < chkBoxCount; i++)
     {
       var chkBox = chkboxListWorkTypes.Items[i];
       if (chkBox.Selected) continue;
       foreach (DataRow dr in dtResult.Rows)
       {
          string rowValue = (string)dr["WorkTypeID"];
          if (chkBox.Value.Equals(rowValue)) 
          {
             chkBox.Selected = true;
             break;
          }
       }
     }
    

  6. Assuming you don't care about culture or case sensitive comparisons, we can use OrdinalIgnoreCase:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     for (var i = 0; i < chkBoxCount; i++)
     {
       var chkBox = chkboxListWorkTypes.Items[i];
       if (chkBox.Selected) continue;
       foreach (DataRow dr in dtResult.Rows)
       {
          string rowValue = (string)dr["WorkTypeID"];
          if (string.Equals(chkBox.Value, rowValue, StringComparison.OrdinalIgnoreCase)) 
          {
             chkBox.Selected = true;
             break;
          }
       }
     }
    

That's about the best I can do. I'd be surprised if there was any measurable difference on such a small dataset. So, here's what you should really do:

 var workTypeIds = dtResult.Rows.Cast<DataRow>().Select(dr => (string)dr["WorkTypeId"]);
 foreach (var chk in chkBoxListWorkTypes) 
 {
     if (workTypeIds.Contains(chk.Value))
     {
        chk.Selected = true;
     }
 }    

Or, with an Each extension:

 var workTypeIds = dtResult.Rows.Cast<DataRow>().Select(dr => (string)dr["WorkTypeId"]);
 chkBoxListWorkTypes.Where(c => workTypeIds.Contains(c.Value)).Each(c => c.Selected = true);

which may be slightly slower, but reads a lot better IMO.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文