Something like a VLOOKUP
本文关键字:VLOOKUP like Something | 更新日期: 2023-09-27 18:32:22
我正在尝试合并两个不同对象的列表,其中特定字段(employeeID)等于另一个列表中的特定字段[0,0]。我的代码如下所示:
int i = Users.Count() - 1;
int i2 = oracleQuery.Count() - 1;
for (int c = 0; c <= i; c++)
{
for (int d = 0; d <= i2; d++)
{
if (Users[c].getEmployeeID().ToString() == oracleQuery[d][0,0].ToString())
{
Users[c].setIDMStatus(oracleQuery[d][0,1].ToString());
}
}
}
这行得通...但它似乎没有效率。关于更高效的代码的任何建议,最终将导致包含 oracleQuery 列表中的新信息的用户列表?
您可以将 join 与 Enumerable.Join 一起使用:
var matches = Users.Join(oracleQuery,
u => u.getEmployeeId().ToString(),
oq => oq[0,0].ToString(),
(u,oc) => new { User = u, Status = oc[0,1].ToString() });
foreach(var match in matches)
match.User.setIDMStatus(match.Status);
请注意,如果 getEmployeeId()
和 oracleQuery 的 [0,0]
元素属于同一类型,则可以消除ToString()
调用。
就
效率而言,我唯一注意到的是您使用 Enumerable.Count() 方法,该方法在 for 循环中再次显式循环之前枚举结果。我认为 LINQ 实现将摆脱通过结果来计算元素。
我不知道您对使用 LINQ 查询表达式有何感受,但这是我最喜欢的:
var matched = from user in Users
join item in oracleQuery on user.getEmployeeID().ToString() equals item[0,0].ToString()
select new {user = user, IDMStatus = item[0,1] };
foreach (var pair in matched)
{
pair.user.setIDMStatus(pair.IDMStatus);
}
你也可以使用嵌套的foreach循环(如果有多个匹配项并且set被多次调用):
foreach (var user in Users)
{
foreach (var match in oracleQuery.Where(item => user.getEmployeeID().ToString() == item[0,0].ToString()) {
user.setIDMStatus(match[0,1]);
}
}
或者,如果肯定只有一个匹配项:
foreach (var user in Users)
{
var match = oracleQuery.SingleOrDefault(item => user.getEmployeeID().ToString() == item[0,0].ToString());
if (match != null) {
user.setIDMStatus(match[0,1]);
}
}
我认为您编写的内容中没有任何真正的效率问题,但是您可以根据 LINQ 中的实现对其进行基准测试。我认为使用 foreach
或 Linq query expression
可能会使代码更易于阅读,但我认为效率没有问题。还可以使用 LINQ 方法语法编写 LINQ 查询表达式,就像在另一个答案中所做的那样。
如果数据来自数据库,您可以在那里进行连接。 否则,您可以对两个列表进行排序并执行比现在更快的合并联接。
但是,自从 C# 引入 LINQ 以来,有很多方法可以在代码中执行此操作。 只需使用 linq 查找即可加入/合并列表。