代码之家  ›  专栏  ›  技术社区  ›  kxf951

对象数组与自定义标头的比较

  •  1
  • kxf951  · 技术社区  · 10 年前

    我有一个从两个vcenter中提取的角色对象数组。

    我正在尝试制作一个有3列的格式化表:角色、主、从

    后两列中有“存在”或“缺失”。

    我认为发生的问题是,当它发现主列中存在角色时,它会以某种方式将从属列标记为“缺失”,尽管我知道它在那里。

    我刚进入Powershell几个月,有人能看出我的逻辑有什么问题吗?

    edit:RoleTable。所有角色,角色表。MasterRoles和RoleTable。从属角色都是对象数组

        $RoleTable.AllRoles | Select-Object Name, 
        @{Name = "Master Server"; Expression = {if ($RoleTable.MasterRoles -contains $_) {"EXISTS"} else {"MISSING"}}}, 
        @{Name = "Slave Server"; Expression = {if ($RoleTable.SlaveRoles -contains $_) {"EXISTS"} else {"MISSING"}}}
    

    Roletable示例。Allroles对象:

    $RoleTable.AllRoles[1] | Select-Object *
    
    
    Description   : Not logged-in user (cannot be granted)
    IsSystem      : True
    PrivilegeList : {System.Anonymous}
    ServerId      : /VIServer=someuser@xxxx-xxxx:443/
    Server        : 
    Id            : -4
    Name          : Anonymous
    Uid           : /VIServer=someuser@xxxx-xxxx:Role=-4/
    ExtensionData : VMware.Vim.AuthorizationRole
    Client        : VMware.VimAutomation.ViCore.Impl.V1.VimClient
    
    1 回复  |  直到 10 年前
        1
  •  2
  •   Mathias R. Jessen    10 年前

    除非 $RoleTable.AllRoles[1] 和中的一项 $RoleTable.SlaveRoles 提到 内存中完全相同的对象 , -contains 将返回 $false ,即使 看似 中存在相同的对象 $RoleTable.SlaveRoles .

    (这是 只有 对于引用类型为true,而不是值类型)

    这应该说明区别:

    对同一对象的引用:

    PS C:\> $Collection = @(New-Object psobject -Property @{p=123})
    PS C:\> $Item       = $Collection[0]
    PS C:\> $Collection -contains $Item 
    True 
    

    对相同对象的引用:

    PS C:\> $Collection = @(New-Object psobject -Property @{p=123})
    PS C:\> $Item       = New-Object psobject -Property @{p=123}
    PS C:\> $Collection -contains $Item 
    False
    

    在您的示例中,可以使用 Name 或角色 Id 属性(由@jisaak建议):

    $RoleTable.AllRoles | Select-Object Name, 
    @{Name = "OnMaster"; Expression = {$RoleTable.MasterRoles.Id -contains $_.Id}}, 
    @{Name = "OnSlave"; Expression = {$RoleTable.SlaveRoles.Id -contains $_.Id}}
    

    如上所示,我可能会使用通用布尔值作为指示符,而不是字符串


    这种行为在.NET中是一种刻意的性能优化——你永远不知道要确保对象的所有内部属性的精确值比较,你需要深入到多深的“兔子洞”。

    另一方面,值类型更容易执行相等比较(也不一定有内存引用进行比较),结果是:

    [int]

    PS C:\> $Collection = @(283)
    PS C:\> $Item       = $Collection[0]
    PS C:\> $Collection -contains $Item
    True
    PS C:\> $Item       = 283
    PS C:\> $Collection -contains $Item
    True
    

    [string] :

    PS C:\> $Collection = @("SomeString")
    PS C:\> $Item       = $Collection[0]
    PS C:\> $Collection -contains $Item
    True
    PS C:\> $Item       = "SomeString"
    PS C:\> $Collection -contains $Item
    True
    

    等等

    推荐文章