【问题标题】:Complicated Intersection With Maps与地图的复杂交叉点
【发布时间】:2015-04-01 22:39:56
【问题描述】:

我有两个相同 K、V 类型的地图,这样

关键是国家

值是

的映射

所以整体的Map结构是

 Map <String, Map<String, List<City>>> m1, m2;

现在我想找出地图的哪些条目是相同的,哪些是不同的

例如:

m1 =    { India = [TA -> {City1, City2, City3}   KA -> {City1, City2}]
          USA =   [WI -> {City1, City2, City3},  OH -> {City1, City2}] }

m2 =    { India = [TA -> {City1, City2, City3} ]
          USA =   [WI -> {City1, City3},         DC -> {City1}] }

输出应该是

Common = { India = [TA -> {City1, City2, City3} ]
           USA = [WI -> {City1, City3}] }

有没有比遍历整个列表并逐行检查更好的方法来获取此信息(即使已经定义了执行此操作的方法,它也会很棒)?

我将使用它,以便我知道在过去几年中唯一改变的是少数几个城市和少数几个州。

如果需要,我们很乐意进一步澄清。

提前致谢。

【问题讨论】:

    标签: dictionary set-theory


    【解决方案1】:

    很大程度上取决于您将用于存储数据的集合类型。另一个因素是您将要使用的技术。然后它还取决于代码的效率与可读性。我最喜欢的语言是 C#,所以我会选择它。然后像Dictionary&lt;string, Dictionary&lt;string, List&lt;City&gt;&gt;&gt;一样实现整个事情——类似于你的建议。

    为了获取数据,我使用了 LINQ,因为它为您提供了可读性很强的代码。

    我实现了您的示例如下(为简单起见,城市是简单的字符串):

    var m1 = new Dictionary<string,Dictionary<string,List<string>>>
    {
        {
            "India", new Dictionary<string, List<string>> 
                        {
                            {"TA", new List<string> {"City1", "City2", "City3"}},
                            {"KA", new List<string> {"City1", "City2"}}
                        }
        },
        {
            "USA", new Dictionary<string, List<string>> 
                        {
                            {"WI", new List<string> {"City1", "City2", "City3"}},
                            {"OH", new List<string> {"City1", "City2"}}
                        }
        }
    };
    
    var m2 = new Dictionary<string,Dictionary<string,List<string>>>
    {
        {
            "India", new Dictionary<string, List<string>> 
                        {
                            {"TA", new List<string> {"City1", "City2", "City3"}},
                        }
        },
        {
            "USA", new Dictionary<string, List<string>> 
                        {
                            {"WI", new List<string> {"City1", "City3"}},
                            {"DC", new List<string> {"City1"}}
                        }
        }
    };
    

    获取结果的操作是应用于嵌套集合的每一层的Intersect 方法:

    var result = m1.Keys.Intersect(m2.Keys)
                        .ToDictionary(k => k, k => m1[k].Keys.Intersect(m2[k].Keys)
                            .ToDictionary(l => l, l => m1[k][l].Intersect(m2[k][l])));
    

    如果您对其进行调试并展开 result,您将看到它返回您在示例中所期望的值。

    请注意,您的City 类必须实现IEquatable&lt;T&gt; 接口,以便它可以在Intersect 方法中正确处理。 MSDN上的示例实现

    【讨论】:

    • 合理的逻辑。这次真是万分感谢。我会试一试,如果它工作正常就回来:)。再次感谢
    • 正如回复中提到的,我在简单的字符串上对其进行了测试。如果您将字典和查询复制到 Visual Studio 项目中并运行它,您将获得结果。但是对于City 类,您需要实现IEquatable 接口来测试它是否正常工作。
    【解决方案2】:

    对于这两个地图,最好的方法是通过每个键递增。

    但是,对于列表,如果列表已排序,请在列表的元素之间使用binary search

    干杯!

    【讨论】:

    • 我明白了,谢谢你的想法。不幸的是,它们没有排序。
    • 在这种情况下,可能是先堆排序然后二分查找。
    猜你喜欢
    • 1970-01-01
    • 2016-09-19
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 2015-12-27
    • 1970-01-01
    相关资源
    最近更新 更多