【问题标题】:Object Array Comparison with Custom Headers对象数组与自定义标头的比较
【发布时间】:2015-10-29 16:23:32
【问题描述】:

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

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

后两列会出现“存在”或“缺失”。

我认为发生的问题是,当它发现该角色存在于 master 中时,它会以某种方式将 slave 列标记为“丢失”,即使我知道它在那里。

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

编辑:RoleTable.AllRoles、RoleTable.MasterRoles 和 RoleTable.SlaveRoles 都是对象数组

    $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

【问题讨论】:

  • 你能提供一个 RoleTable 对象的例子吗?
  • ID 是唯一的吗?如果是这样,您可以尝试将您的 if 语句更改为: if (($RoleTable.SlaveRoles | select Id) -contains $_.Id)
  • 让我试试吧! ID 是唯一的

标签: powershell scripting vmware


【解决方案1】:

除非$RoleTable.AllRoles[1]$RoleTable.SlaveRoles 中的项目引用内存中完全相同的对象,否则-contains 将返回$false,即使一个看似相同的对象存在于$RoleTable.SlaveRoles

(这适用于引用类型,而不适用于值类型)

这应该说明区别:

引用同一对象:

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

等等……

【讨论】:

  • 所以你留下来而不是比较对象是否相同,我应该检查它是否具有相同的 .Name 字符串或什么?
  • 是的,这就是重点,这就是为什么我建议你比较 ID ;)
  • @kxf951 是的,完全正确。我会用一个例子来更新答案
猜你喜欢
  • 2016-11-20
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多