将Datatable与另一个进行比较以查看它是否具有正确的格式

时间:2013-03-05 08:45:03

标签: c#

我有2个DataTables:TableNumber包含手机号码和TableCode,其中包含所有可能的移动代码的混合,所有移动代码都是6位数字。我想创建一个列表,只有6个第一个数字来自TableCode的数字,所以不会考虑其第一个数字不在TableCode中的任何数字。我用foreach,.Contains(),IndexOf()尝试了这个,但都很慢,因为数字中的记录超过100,000,循环所有项目需要很长时间。并与另一张桌子比较。我使用2个嵌套的foreach循环。我正在做一些愚蠢的事情我认为2 foreach因为那将是30亿搜索来自TableCode的30,000名成员,我花了5分钟给我结果。我的代码是这样的:

foreach(string codetable in TableCode)
     {
          foreach(string grouptable in TableNumber)
                 {
                    if(grouptable.IndexOf(codetable)!=-1)
                    {
                        //work here
                    }
                 }
     }

这里我已经将表'Number rows'添加到一个只包含数字的列表中,所以我在这里搜索列表,但是在尝试再次比较DataTables时它与此类似,这需要太长时间。

2 个答案:

答案 0 :(得分:3)

或许可以按照以下方式将数据表转换为IEnumerable:Convert DataTable to IEnumerable<T>

然后可能使用yield return并且可能处理单独线程上的处理,甚至使用LINQ进行过滤。

也许在表上实现一些排序,并将它们分成更小的块,并为并行处理产生更多的线程。

答案 1 :(得分:1)

因此,TableNumber是您要用来过滤TableCode - DataTable的“肯定”表格。

所以模型与此类似:

var TableNumber = new DataTable();
var TableCode = new DataTable();
TableNumber.Columns.Add("MobileNumbers", typeof(string));
TableCode.Columns.Add("MobileCode", typeof(string));

然后,您可以使用包含所有有效数字的HashSet<string>Enumerable.Join将第二个表中的行与有效数字相关联:

var numbersFirst6digits = TableNumber.AsEnumerable()
    .Select(r => new string(r.Field<string>("MobileNumbers").Where(Char.IsDigit).Take(6).ToArray()));
var dictionary = new HashSet<string>(numbersFirst6digits);

var validCodeRows = from row in TableCode.AsEnumerable()
                    join num in dictionary
                    on row.Field<string>("MobileCode") equals num
                    select row;
// if you need a new DataTable:
DataTable tblValidCodes = validCodeRows.CopyToDataTable();

如果您不需要过滤前6位数的第一个表,则可以替换此行:

.Select(r => new string(r.Field<string>("MobileNumbers").Where(Char.IsDigit).Take(6).ToArray()));

.Select(r => {var mNum = r.Field<string>("MobileNumbers"); return mNum.Length < 6 ? mNum : mNum.Substring(0, 6)};);