2015-08-06 4 views
1

У меня есть массив объектов, которые я вытащил из двух vcenters.Сравнение массивов объектов с пользовательскими заголовками

Я пытаюсь сделать форматированный таблицу, которая имеет 3 колонки: роли, ведущий, ведомый

Там будет «существует» или «отсутствует» в последних двух столбцах.

Проблема, которая, как я полагаю, происходит, когда обнаруживает, что эта роль существует у мастера, она как-то маркирует рабочую колонку как «отсутствующую», хотя я знаю, что она есть.

Я всего лишь несколько месяцев в 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  : /[email protected]:443/ 
Server  : 
Id   : -4 
Name   : Anonymous 
Uid   : /[email protected]:Role=-4/ 
ExtensionData : VMware.Vim.AuthorizationRole 
Client  : VMware.VimAutomation.ViCore.Impl.V1.VimClient 
+0

Вы можете указать пример объекта RoleTable? –

+0

Да! Один момент. – kxf951

+1

Является ли идентификатор уникальным? Если это так, вы можете попытаться изменить свой оператор if: if (($ RoleTable.SlaveRoles | select Id) -contains $ _. Id) –

ответ

2

Если только $RoleTable.AllRoles[1] и элемент в $RoleTable.SlaveRoles см. тот же самый объект в памяти, -contains вернется $false, канун n, если похоже идентичный объект существует в $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 

и так далее ...

+0

Итак, ваше пребывание вместо сравнения, если объект тот же, я должен проверить, имеет ли он ту же строку .Name или что-то еще? – kxf951

+1

Да, это пункт, и именно поэтому я предложил вам сравнить идентификаторы;) –

+0

Спасибо, сэр! :) – kxf951

Смежные вопросы