1

我有 2 个数据表:包含手机号码的 TableNumber 和包含所有可能的移动代码的混合的 TableCode,总共 6 位数。我想创建一个列表,仅包含其前 6 个数字来自 TableCode 的数字,因此不会考虑其第一个数字不在 TableCode 中的任何数字。我已经用 foreach、.Contains()、IndexOf() 尝试过这个,但它们都很慢,因为数字记录超过 100,000 条,并且遍历所有项目需要很长时间。并与另一张表进行比较。我使用 2 个嵌套的 foreach 循环。我在用 2 个 foreach 做一些愚蠢的事情,因为这将是对来自 TableCode 的 30,000 个成员的 30 亿次搜索,我需要 5 分钟才能给出结果。我的代码是这样的:

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

在这里,我已将表的数字行添加到仅包含数字的列表中,所以在这里我正在搜索列表,但在尝试再次比较 DataTables 时与此类似,它需要的时间太长。

4

2 回答 2

3

或许将数据表转换为 IEnumerable,如下所示:Convert DataTable to IEnumerable<T>

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

也许对表进行一些排序并将它们分成更小的块,并产生更多的线程进行并行处理。

于 2013-03-05T09:04:33.500 回答
1

TableNumber您要用来过滤TableCode-的“肯定”表也是如此DataTable

所以模型类似于这样:

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

然后,您可以将 aHashSet<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)};);
于 2013-03-05T09:24:27.520 回答