Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 改进重复检查方法_C#_.net_Winforms_Datagridview_Duplicates - Fatal编程技术网

C# 改进重复检查方法

C# 改进重复检查方法,c#,.net,winforms,datagridview,duplicates,C#,.net,Winforms,Datagridview,Duplicates,早上好,伙计们 使用C sharp.net4和MS Visual Studio 2010 我已经为我的windows窗体程序开发了一个复制检查器。 当我的数据网格上有几百条记录时,它工作得非常完美,几乎是即时的 我注意到的问题是,当显示6000条记录时,效率根本不够,需要几分钟的时间 我想知道是否有人有一些好的技巧可以让这个方法更快,或者是改进现有的设计,或者是一个不同的方法,我已经看过了 再次感谢您的帮助 代码如下: public void CheckForDuplicate() {

早上好,伙计们

使用C sharp.net4和MS Visual Studio 2010

我已经为我的windows窗体程序开发了一个复制检查器。 当我的数据网格上有几百条记录时,它工作得非常完美,几乎是即时的

我注意到的问题是,当显示6000条记录时,效率根本不够,需要几分钟的时间

我想知道是否有人有一些好的技巧可以让这个方法更快,或者是改进现有的设计,或者是一个不同的方法,我已经看过了

再次感谢您的帮助

代码如下:

public void CheckForDuplicate()
{
    DataGridViewRowCollection coll = ParetoGrid.Rows;
    DataGridViewRowCollection colls = ParetoGrid.Rows;
    IList<String> listParts = new List<String>();
    int count = 0;

    foreach (DataGridViewRow item in coll)
    {
        foreach (DataGridViewRow items in colls)
        {
            count++;
            if ((items.Cells["NewPareto"].Value != null) && (items.Cells["NewPareto"].Value != DBNull.Value))
            {
                if ((items.Cells["NewPareto"].Value != DBNull.Value) && (items.Cells["NewPareto"].Value != null) && (items.Cells["NewPareto"].Value.Equals(item.Cells["NewPareto"].Value)))
                {
                    if ((items.Cells["Part"].Value != DBNull.Value) && (items.Cells["Part"].Value != null) && !(items.Cells["Part"].Value.Equals(item.Cells["Part"].Value)))
                    {
                        listParts.Add(items.Cells["Part"].Value.ToString());

                        dupi = true; //boolean toggle
                    }
                }
            }
        }
    }  
    MyErrorGrid.DataSource = listParts.Select(x => new { Part = x }).ToList();     
}
public void CheckForDuplicate()
{
DataGridViewRowCollection coll=ParetoGrid.Rows;
DataGridViewRowCollection colls=ParetoGrid.Rows;
IList listParts=新列表();
整数计数=0;
foreach(coll中的DataGridViewRow项)
{
foreach(colls中的DataGridViewRow项)
{
计数++;
if((items.Cells[“NewPareto”].Value!=null)和&(items.Cells[“NewPareto”].Value!=DBNull.Value))
{
if((items.Cells[“NewPareto”].Value!=DBNull.Value)&&(items.Cells[“NewPareto”].Value!=null)&&(items.Cells[“NewPareto”].Value.Equals(item.Cells[“NewPareto”].Value)))
{
if((items.Cells[“Part”].Value!=DBNull.Value)&&&(items.Cells[“Part”].Value!=null)&&&!(items.Cells[“Part”].Value.Equals(item.Cells[“Part”].Value)))
{
添加(items.Cells[“Part”].Value.ToString());
dupi=true;//布尔切换
}
}
}
}
}  
MyErrorGrid.DataSource=listParts.Select(x=>new{Part=x}).ToList();
}

任何问题都会让我知道,我会尽力回答。

有一种方法可以让这更有效。您需要计算每个项目的哈希值。具有不同散列的项不可能是重复项


一旦你有了散列,你可以通过散列进行排序,或者使用一个具有有效键控检索的数据结构(如
字典
)来查找所有的重复项。

如果可以,你应该尝试在基础数据上而不是在UI对象上这样做-但是我有一种预感,你是从一组数据行中播种数据,在这种情况下,您可能无法做到这一点

我认为这里的问题很大一部分是重复按名称取消对单元格的引用,以及重复遵从第二组单元格的事实。因此,请提前做好准备:

var first = (from row in coll.Cast<DataGridViewRow>()
            let newpareto = row.Cells["NewPareto"].Value ?? DBNull.Value
            let part = row.Cells["Part"].Value ?? DBNull.Value
            where newpareto != DBNull.Value && part != DBNull.Value
            select new 
            { newpareto = newpareto, part = part }).ToArray();

//identical - so a copy-paste job (if not using anonymous type we could refactor)
var second = (from row in colls.Cast<DataGridViewRow>()
            let newpareto = row.Cells["NewPareto"].Value ?? DBNull.Value
            let part = row.Cells["Part"].Value ?? DBNull.Value
            where newpareto != DBNull.Value && part != DBNull.Value
            select new 
            { newpareto = newpareto, part = part }).ToArray();


//now produce our list of strings
var listParts = (from f in first
                where second.Any(v => v.newpareto.Equals(f.newpareto)
                                   && !v.part.Equals(f.part))
                select f.part.ToString()).ToList(); //if you want it as a list.
var first=(从coll.Cast()中的行开始)
设newpareto=row.Cells[“newpareto”].Value??DBNull.Value
let part=行.单元格[“part”].Value??DBNull.Value
其中newpareto!=DBNull.Value&&part!=DBNull.Value
选择新的
{newpareto=newpareto,part=part}).ToArray();
//相同-因此是复制粘贴作业(如果不使用匿名类型,我们可以重构)
var second=(从colls.Cast()中的行开始)
设newpareto=row.Cells[“newpareto”].Value??DBNull.Value
let part=行.单元格[“part”].Value??DBNull.Value
其中newpareto!=DBNull.Value&&part!=DBNull.Value
选择新的
{newpareto=newpareto,part=part}).ToArray();
//现在产生我们的字符串列表
var listParts=(从第一个中的f开始)
其中second.Any(v=>v.newpareto.Equals(f.newpareto)
&&!v部分等于(f部分))
选择f.part.ToString()).ToList()//如果你想把它列为一个列表。

一个简单的优化,不会对代码造成太大的更改,不要查看所有列两次,外部循环循环所有列,内部循环从外部循环所在的位置循环到末尾。单元格[“NewPareto”]是字符串查找。如果你在循环外得到一个数字(表在循环中不会改变),然后通过数字访问呢?最初的原因是我循环得到第一个值,然后用它作为基础,我通过第二个循环检查所有其他值,看是否有匹配项。@StevenSmith如果你看了我的答案,我应该补充一点,我刚刚更改了它,以获得一个更好的解决方案,这意味着你每行只查找一次单元格。啊,我来看看,舒德缩短了我的时间!虽然我原则上同意,但这不是一个简单的解决方案:如何为单元格或DBNulls中的空值计算哈希?如果采用明显的方法并使用
0
,则无法在此处的相等逻辑上实现短路,其中任何带有
null
DBNull.Value
的单元格都会被自动忽略。您将强制字典对这些行执行更长的相等性检查,因为它们将共享相同的哈希。@AndrasZoltan是的,此算法要求您对某些最终不同的项执行检查。这是它的基本属性。改进仍然很大,因为您不再需要进行6000*6000/2比较。使用哈希非常有趣,虽然我以前从未尝试过,但我对我在代码中实现它的技能有点怀疑这是另一个有趣的问题,同样-我最初错过了一个,直到Eren在我的第一个解决方案中指出它-这里的重复实际上是一个字段相等,另一个字段不相等-这不可能在单个哈希中实现。要匹配有问题的代码,这应该是
&&!part1.Equals(part2)
好的,我做了一些测试,用我的版本做了3次,用你的版本做了3次。根据4832条记录,地雷需要1分21秒才能完成。你的需要57秒才能完成。这是一个好消息,因为它可以节省24秒的时间,但仍然需要改进。hehegona试试看,您的新解决方案看起来快多了!设newpareto=行[“newpareto”]。值??DBNull.Value无法将索引应用于