使用linq过滤对象列表

时间:2017-10-01 13:17:13

标签: c# linq

我有以下方式的观点

public class dettails
    {
        public string server { get; set; }
        public string details1 { get; set; }
        public string details2 { get; set; }
        public string version    { get; set; }

        public dettails(string Server, string Details1, string Details2, string Version)
        {
            server = Server;
            details1 = Details1;
            details2 = Details2;
            version = Version;
        }
    }

以下是存储在对象列表中的数据。

Server1, Database, MySQL, 5.5
Server2, Database, MySQL, 5.1
Server3, OS, Ubuntu, 10.04
Server1, OS, Ubuntu, 10.04
Server2, OS, Ubuntu, 12.04
Server3, Language, Python, 2.6.3

数据已存储在对象列表中。我想要的输出是以下面的方式

在至少2个不同的服务器上安装了过时版本(即非最新版本的版本)的软件包名称列表。

因此,在这种情况下,程序的输出应为:

Ubuntu因为Ubuntu 10.04是一个过时的版本(最新版本是12.04),它安装在两个服务器(服务器3和服务器1)上。

我如何使用linq实现它。请指教。

1 个答案:

答案 0 :(得分:0)

您应该有办法找出每个操作系统的最新版本。没有这些信息,就很难实现。

我们可以假装我们在任何服务器上找到的最新版本是"最新版本",但这不是很准确。

如果我们有办法生成一个唯一密钥,那么让我们说:

string AssemlbeKey(dettails serverInfo) => $"{serverInfo.details1}, {serverInfo.details2}";

然后我们可以构建一个字典来确定在给定集合中的任何服务器上安装的最新版本:

var dictPretendedMostRecentVersionsByDetails = ServerCollection
    .GroupBy(entry => AssembleKey(entry))
    .ToDictionary(
        group => group.Key, 
        group => group.Value
            .OrderByDescending(entry => Version.Parse(entry.version))
            .First()
    );

现在我们已经了解了什么是"弃用",我们可以扫描服务器集合。

var deprecatedCollection = ServerCollection
    .Select(entry => new KeyValuePair<string, ServerInfo>(AssembleKey(entry), entry)
    .Where(entry => dictPretendedMostRecentVersionsByDetails[entry.Key] < Version.Parse(entry.version))
    .Select(entry => entry.Value);

然后你应该有一组不推荐使用的服务器细节,现在可以枚举它并做你想做的任何事情(例如用控制台写入所有必要的信息)。