嵌套的 foreach 循环 returns 仅不同
nested foreach loops returns only distinct
我有一个数据库,其中每个电子邮件地址都应该属于一个唯一的客户,但我有很多重复项。我使用 sql 查询来列出每次出现的客户 ID 和电子邮件地址对,其中有多个客户 ID 映射到一个电子邮件地址。结果看起来像这样(更改地址以保护无辜者)
Customer ID Email
101233 bob@myaddress.com
108993 bob@myaddress.com
113224 bob@myaddress.com
89223 mary@otherdomain.com
188223 mary@otherdomain.com
在 c# 中,我将其填充到名为 dt 的数据表中,其中包含 722 行。我用它来制作第二个名为 distinctTbl 的数据表,它有 344 行,只包含不同的电子邮件地址,使用这个:
DataTable distinctTbl = dt.AsDataView().ToTable(true, "Email");
我正在尝试使用嵌套循环为每个电子邮件地址制作一个整数列表(客户 ID):
foreach (DataRow dr in distinctTbl.Rows)
{
// for each email address:
List<int> idNums = new List<int>();
foreach (DataRow myRow in dt.Rows)
{
// for every customerID / email pair in the original table
if (myRow["Email"] == dr["Email"])
{
idNums.Add((int)myRow["CustomerID"]);
}
}
// Do something with the List<int> before exiting outside loop
}
当我运行这段代码时,每个整数列表只包含一个值。该值是正确的,但每个电子邮件地址至少应有两个。我进行了足够多的调试,发现它始终正确识别第一个匹配项,但会跳过任何后续匹配项。我确定我遗漏了一些明显的东西,但是有人看到发生了什么吗?
一个快速简单的解决方案是使用 Dictionary<string,List<int>>
而不是列表:
Dictionary<string, List<int>> idNums = new Dictionary<string, List<int>>();
foreach (DataRow myRow in dt.Rows)
{
string email = myRow["Email"].ToString()
if (idNums.ContainsKey(email))
{
idNums[email].Add((int)myRow["CustomerID"]);
}
else
{
idNums.Add(email, new List<int> { (int)myRow["CustomerID"] });
}
}
现在 idNums 将包含与每封电子邮件关联的 ID 列表。
放弃 foreach
循环。
您可以使用 Linq 更轻松地获取您正在寻找的信息。
Dictionary<string, List<int>> emailIDs =
dt.Rows.OfType<DataRow>()
.GroupBy(row => (string)row["Email"])
.ToDictionary(grp => grp.Key,
grp => grp.Select(row => (int)row["CustomerID"]).ToList());
我有一个数据库,其中每个电子邮件地址都应该属于一个唯一的客户,但我有很多重复项。我使用 sql 查询来列出每次出现的客户 ID 和电子邮件地址对,其中有多个客户 ID 映射到一个电子邮件地址。结果看起来像这样(更改地址以保护无辜者)
Customer ID Email
101233 bob@myaddress.com
108993 bob@myaddress.com
113224 bob@myaddress.com
89223 mary@otherdomain.com
188223 mary@otherdomain.com
在 c# 中,我将其填充到名为 dt 的数据表中,其中包含 722 行。我用它来制作第二个名为 distinctTbl 的数据表,它有 344 行,只包含不同的电子邮件地址,使用这个:
DataTable distinctTbl = dt.AsDataView().ToTable(true, "Email");
我正在尝试使用嵌套循环为每个电子邮件地址制作一个整数列表(客户 ID):
foreach (DataRow dr in distinctTbl.Rows)
{
// for each email address:
List<int> idNums = new List<int>();
foreach (DataRow myRow in dt.Rows)
{
// for every customerID / email pair in the original table
if (myRow["Email"] == dr["Email"])
{
idNums.Add((int)myRow["CustomerID"]);
}
}
// Do something with the List<int> before exiting outside loop
}
当我运行这段代码时,每个整数列表只包含一个值。该值是正确的,但每个电子邮件地址至少应有两个。我进行了足够多的调试,发现它始终正确识别第一个匹配项,但会跳过任何后续匹配项。我确定我遗漏了一些明显的东西,但是有人看到发生了什么吗?
一个快速简单的解决方案是使用 Dictionary<string,List<int>>
而不是列表:
Dictionary<string, List<int>> idNums = new Dictionary<string, List<int>>();
foreach (DataRow myRow in dt.Rows)
{
string email = myRow["Email"].ToString()
if (idNums.ContainsKey(email))
{
idNums[email].Add((int)myRow["CustomerID"]);
}
else
{
idNums.Add(email, new List<int> { (int)myRow["CustomerID"] });
}
}
现在 idNums 将包含与每封电子邮件关联的 ID 列表。
放弃 foreach
循环。
您可以使用 Linq 更轻松地获取您正在寻找的信息。
Dictionary<string, List<int>> emailIDs =
dt.Rows.OfType<DataRow>()
.GroupBy(row => (string)row["Email"])
.ToDictionary(grp => grp.Key,
grp => grp.Select(row => (int)row["CustomerID"]).ToList());