如何按属性对对象列表进行排序

时间:2013-10-23 14:36:06

标签: c# .net performance .net-3.5

我有这段代码:

        DataTable dt = new DataTable();

        dt.Columns.Add("Status");
        dt.Columns.Add("File");
        dt.Columns.Add("Revision");
        int i = 0;

        foreach (SvnStatusEventArgs status in statuses) // statuses is a Collection
        {
            dt.Rows.Add();

            switch (status.LocalContentStatus)
            { 
                case SvnStatus.NotVersioned:
                    dt.Rows[i]["Status"] = "Not Versioned";
                    break;
                default:
                    dt.Rows[i]["Status"] = status.LocalContentStatus.ToString();
                    break;
            }

            dt.Rows[i]["File"] = status.Path;

            foreach(SvnInfoEventArgs info in infos) //infos is a Collection
            {
                if (status.Path.Equals(info.Path))
                {
                    dt.Rows[i]["Revision"] = info.Revision;
                    break;
                }
            }

            i++;
        }

statusesinfos每行最多可以有20K行,所以我的嵌套foreach可能需要很长时间。

如果我将这些收藏品转换为列表然后尝试按Path对它们进行排序,我想我可以加快速度。

查看Sort方法的MSDN Page,我不知道如何比较SvnStatusEventArgs [n]和SvnStatusEventArgs [n + 1]中的Path字段。然后我也开始怀疑,因为我将完全迭代这两组对象并对它们进行排序,这真的比我现有的代码更有效吗?我想它会是n * 2而不是n * n,对吧?

对于它的价值,我试图排序的Path字段只是一个字符串。

3 个答案:

答案 0 :(得分:5)

您可以创建Dictionary<string, int>(键是路径,修订后的值)。

Dictionary<string, int> pathRevisions = infos
    .GroupBy(info => info.Path)
    .ToDictionary(group => group.Key, group => group.First().Revision);

.... 在循环中:

int revision;
if(pathRevisions.TryGetValue(status.Path, out revision))
    dt.Rows[i].SetField("Revision", revision);

答案 1 :(得分:1)

你的问题还不清楚,但既然你在评论中说过这就是你的意思

foreach (SvnStatusEventArgs status 
         in statuses
         .OrderBy(x => x.Path))

这是一种非常基本的方法。如果你想要一个更优的,你应该使用Tim Schmelter的解决方案。

答案 2 :(得分:1)

最好只是在信息上制作字典 - 用键作为路径。这将是最有效的整体。