【问题标题】:Powershell: Union list of hashtable - taking the latest one on collisionPowershell:哈希表的联合列表 - 采用最新的碰撞
【发布时间】:2020-02-10 19:53:28
【问题描述】:

我目前正在尝试合并一个包含 N 个哈希表的列表 - 其中每个表都包含一个时间戳以及另一个哈希表列表。

这个想法是联合哈希表列表并与来自具有最高时间戳的表中的一行发生冲突。

举个例子:

@(
    @{
       week = '2020-05'
       participants = @(
           @{
               name = 'user A'
               age = 35
               address = 'city A'
           },
           @{
               name = 'user B'
               age = 16
               address = 'city B'
           }
       )
    },@{
       week = '2020-04'
       participants = @(
           @{
               name = 'user A'
               age = 35
               address = 'city A'
           },
           @{
               name = 'user B'
               age = 16
               address = 'city A'
           },
           @{
               name = 'user C'
               age = 42
               address = 'city B'
           }
       )
    }
)

请注意,对于解释,我们在 2020-05 年收到了 2 个用户,而在 2020-04 年我们收到了 3 个用户。

现在,最终目标是得到这样的列表:

result = @(
    @{
        week = '2020-05'
        name = 'user A'
        age = 35
        address = 'city A'
    },
    @{
        week = '2020-05'
        name = 'user B'
        age = 16
        address = 'city B'
    },
    @{
        week = '2020-04'
        name = 'user C'
        age = 42
        address = 'city B'
    }
)

我现在的问题是:是否有可能在不需要显式循环的情况下解决这个问题 - 但使用 foreach 或 select 对象?我已经能够使用 select object / distinct 获得一组唯一用户名 - 但在这里我不仅对可能的名称列表感兴趣 - 还对名称/年龄和地址的组合感兴趣。

【问题讨论】:

    标签: powershell hashtable


    【解决方案1】:

    把它放在这里,因为它有代码,因此对于评论部分来说太长了。

    但是...但是,“用户 b”在两个星期内,但地址不同。在正常的想法中,那是两个不同的人,因为他们的住所在两个不同的地方。因此,如果是这种情况,您所追求的最终结果是无效的。

    Clear-Host
    
    @(
        @{
           week = '2020-05'
           participants = @(
               @{
                   name = 'user A'
                   age = 35
                   address = 'city A'
               },
               @{
                   name = 'user B'
                   age = 16
                   address = 'city B'
               }
           )
        },@{
           week = '2020-04'
           participants = @(
               @{
                   name = 'user A'
                   age = 35
                   address = 'city A'
               },
               @{
                   name = 'user B'
                   age = 16
                   address = 'city A'
               },
               @{
                   name = 'user C'
                   age = 42
                   address = 'city B'
               }
           )
        }
    ) | 
    ConvertTo-Json -Depth 3 | 
    ConvertFrom-Json | 
    Select -ExpandProperty SyncRoot | 
    Select Week -ExpandProperty participants
    
    # Results
    <#
    name   age address week   
    ----   --- ------- ----   
    user A  35 city A  2020-05
    user B  16 city B  2020-05
    user A  35 city A  2020-04
    user B  16 city A  2020-04
    user C  42 city B  2020-04
    #>
    

    使用 Select -Unique

    ConvertTo-Json -Depth 3 | 
    ConvertFrom-Json | 
    Select -ExpandProperty SyncRoot | 
    Select Week -ExpandProperty participants | 
    Select -Unique Name, age, address
    
    # Results
    <#
    name   age address
    ----   --- -------
    user A  35 city A 
    user B  16 city B 
    user B  16 city A 
    user C  42 city B
    #>
    

    当然,放弃城市会得到你所追求的三个,好吧,我只是在这里显示名字和年龄。如果用户名不能绝对保证是唯一的,那么,你知道的。

    ConvertTo-Json -Depth 3 | 
    ConvertFrom-Json | 
    Select -ExpandProperty SyncRoot | 
    Select Week -ExpandProperty participants | 
    Select -Unique Name, age
    
    # Results
    <#
    name   age
    ----   ---
    user A  35
    user B  16
    user C  42
    #>
    

    现在在转换回 has 表之前将地址和星期返回到列表中,这是另一回事,因为在最后的 Select 语句中不可用。

    最后,您不使用循环的原因是什么,如果这样可以获得您需要的结果?从我迄今为止的实验来看,与我迄今为止尝试过的以及我在此处发布的内容相比,这样做要简单得多。

    更新

    好的,我想我没有给你这个。真的不知道为什么在我最初的帖子中没有找到它,尤其是在使用 Group-Object 时给了我第一个线索。

    # Convert JSON and use Sort unique to work with data
    Clear-Host
    $HasheTableExport | 
    ConvertTo-Json -Depth 3 | 
    ConvertFrom-Json | 
    Select -ExpandProperty SyncRoot | 
    Select Week -ExpandProperty participants | 
    Sort-Object -Property name -Unique
    
    <#
    # Results
    
    name   age address week   
    ----   --- ------- ----   
    user A  35 city A  2020-05
    user B  16 city B  2020-05
    user C  42 city B  2020-04
    #>
    
    # View as JSON
    Clear-Host
    $HasheTableExport | 
    ConvertTo-Json -Depth 3 | 
    ConvertFrom-Json | 
    Select -ExpandProperty SyncRoot | 
    Select Week -ExpandProperty participants | 
    Sort-Object -Property name -Unique | 
    ConvertTo-Json
    
    # Results
    <#
    [
        {
            "name":  "user A",
            "age":  35,
            "address":  "city A",
            "week":  "2020-05"
        },
        {
            "name":  "user B",
            "age":  16,
            "address":  "city B",
            "week":  "2020-05"
        },
        {
            "name":  "user C",
            "age":  42,
            "address":  "city B",
            "week":  "2020-04"
        }
    ]
    #>
    

    然后根据需要利用/转换。

    【讨论】:

    • 感谢您的快速回复。给你一个快速的背景知识:我要求替代解决方案,因为我认为它可能更有效,因为它可以利用 Powershell 的内置功能。关于名称:尝试将其视为我们每天收到的数据的 PK - 更改地址只是意味着从一周到下一周都有更新。结果,我们希望获得所有周内所有用户的列表 - 以及我们为他们提供的最新数据
    • 但是谢谢你的回复——这已经很有帮助了——现在我只需要找出如果名字上有重复的话如何检索最新的行
    • 不用担心。我还在看它,因为用例的普遍兴趣,看看我是否能完全解决它。如果您这样做了,请务必在其他人之前更新,让所有人从中受益。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 2010-11-16
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    相关资源
    最近更新 更多