像VLOOKUP这样的东西

时间:2013-09-20 20:28:58

标签: c# performance

我正在尝试合并两个不同对象的列表,其中特定字段(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列表的新信息的Users列表?

3 个答案:

答案 0 :(得分:6)

您可以使用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);

请注意,如果ToString()和oracleQuery的getEmployeeId()元素属于同一类型,则可以消除[0,0]次调用。

答案 1 :(得分:1)

就效率而言,我唯一注意到的是你使用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中的实现进行基准测试。我认为使用foreachLinq query expression可能会使代码更容易阅读,但我认为效率没有问题。您也可以使用Linq方法语法编写Linq查询表达式,如在另一个答案中所做的那样。

答案 2 :(得分:0)

如果数据来自数据库,您可以在那里进行连接。否则,您可以对两个列表进行排序,并进行比现在更快的合并连接。

但是,由于C#引入了LINQ,因此在代码中有很多方法可以做到这一点。只需使用linq加入/合并列表即可查找。