#powershell
#powershell
Вопрос:
Если у меня есть хеш-таблица с многозначным именем, как мне указать имя при выполнении поиска?
Вот несколько надуманных примеров…
$unary = @{
$false, "!A";
$true, "A"
}
$unary
Name Value
---- -----
False !A
True A
$unary[$false]
!A
$unary[$true]
A
Пока все хорошо.
$binary = @{
($false, $false) = "!A and !B"
($false, $true) = "!A and B"
($true, $false) = "A and !B"
($true, $true) = "A and B"
}
$binary
Name Value
---- -----
{False, True} !A and B
{True, False} A and !B
{True, True} A and B
{False, False} !A and !B
$binary[$false, $true]
//Nothing
$binary[($false, $true)]
//Nothing
$binary[{$false, $true}]
//Nothing
//www.stackoverflow.com... :)
Что мне нужно указать в $binary[...]
, чтобы получить значение?
Комментарии:
1. Ни в коем случае! Забудьте об этом! Это работало бы на других языках (например, на Ruby works), а не на posh.
Ответ №1:
Ваша проблема в том, что вы используете массивы в качестве ключей в хеш-таблице. Просто чтобы проиллюстрировать, что здесь пошло не так:
PS Home:> $x=$false,$false
PS Home:> $y=@($binary.Keys)[0]
PS Home:> $x
False
False
PS Home:> $y
False
False
PS Home:> $x.Equals($y)
False
Оба объекта также имеют разные хэш-коды. Их никогда не будет хорошей идеей использовать в качестве ключей в хеш-таблицах, поскольку вы не сможете извлечь значения снова, если не будете использовать точно такие же ссылки, которые вы поместили в хеш-таблицу.
Вероятно, проще было бы использовать один объект в качестве ключа:
$binary = @{
0 = "!A and !B"
1 = "!A and B"
10 = "A and !B"
11 = "A and B"
}
или что-то подобное. Затем извлекая
$binary[01]
даст результат "!A and B"
, как и ожидалось.
Обратите также внимание, что Список будет иметь ту же проблему с равенством. Кортежи могут работать, но они недоступны в .NET 2.
Комментарии:
1. Спасибо за объяснение, почему это не работает. Я выбрал комбинацию вашего ответа (укажите ключ с одним значением) и ответа мьолинора (сделайте комбинированный ключ строкой).
Ответ №2:
Это не самое лучшее решение, но в зависимости от того, что вы хотите сделать, оно может помочь.
$unary = new-object ‘object[]’ 2
$unary[$false] = "!A"
$unary[$true] = "A"
$binary= new-object ‘object[,]’ 2,2
$binary[$false,$false] = "!A and !B"
$binary[$false,$true] = "!A and B"
$binary[$true,$false] = "A and !B"
$binary[$true,$true] = "A and B"
Результат :
PS > $binary[$true,$true]
A and B
Ответ №3:
Возможно, это не то, что вы хотели увидеть, но:
$binary = @{
[string]($false,$true) = "!A and B"
[string]($true,$false) = "A and !B"
[string]($true,$true) = "A and B"
}
$binary[[string]($false,$true)]
!A and B
Комментарии:
1.
"$($false,$true)"
был бы более короткий способ сделать это. Или просто"False True"
🙂2. Это короче. В любом случае, это в основном тот же ответ, что и тот, который вы опубликовали, а именно: свести ключи к скаляру.
3. Действительно. Хотя это неуловимо. И требует небольшого знания .NET. Если вы пришли в PowerShell с C #, это, вероятно, довольно очевидно, но в остальном …
4. Спасибо, преобразование моих многозначных ключей в строку было простым изменением того, что у меня уже было, и это просто сработало.