Как добавить одинаковые ключи с разными значениями в хеш-таблицу в PowerShell?

Вот код, в котором я использовал массив хэш-таблиц

$podnumbers = @(1,3,1)

$podInfo = $null
$buffer = 0
$podarray = foreach ($pd in $podnumbers) {
    $podinfo = @()
    for($i=0;$i -lt $pd;$i = $i+1) {
    $pod = Read-Host -Prompt "Assign the pod numbers for",$esxarray[$buffer]
    Write-Output `n
    }
    @{$pd = $pod}
$buffer = $buffer + 1
}

Входные данные, которые я дал для $ pod, - 1 = 1; 3 = 2,4,6; 1 = 3

Я хочу, чтобы мои массивы хеш-таблицы были такими, как показано ниже,

Key : 1
Value : 1
Name : 1

Key : 3
Value : 2,4,6
Name : 3

Key : 1
Value : 3
Name : 1

Но фактический результат, который я получил, таков:

Key : 1
Value : 1
Name : 1

Key : 3
Value : 2
Name : 3

Key : 3
Value : 4
Name : 3

Key : 3
Value : 6
Name : 3

Key : 1
Value : 3
Name : 1

person Django Unchained    schedule 29.10.2020    source источник
comment
Вы этого не делаете - либо добавляете / изменяете существующую ключевую запись, либо находите что-то другое, кроме словаря, для хранения ваших данных :)   -  person Mathias R. Jessen    schedule 29.10.2020
comment
Поскольку кажется, что вы настраиваете модули ESX, возможно, отредактируйте вопрос и объясните, что вы пытаетесь сделать. Скорее всего, вам нужно поменять местами ключи и значения.   -  person vonPryz    schedule 29.10.2020
comment
отредактировал мою цель   -  person Django Unchained    schedule 30.10.2020


Ответы (3)


Если вы хотите добавить несколько значений к одному и тому же ключу, вам необходимо проверить, присутствует ли уже ключ, и действовать соответственно:

$keys = 1,2,3,1
$value = 'a value'
$hashtable = @{}

foreach($key in $keys){
  if(-not $hashtable.ContainsKey($key)){
    # First time we see this key, let's make sure the value is a resizable array
    $hashtable[$key] = @()
  }

  # Now we can safely add values regardless of whether the key already exists
  $hashtable[$key] += $value
}
person Mathias R. Jessen    schedule 29.10.2020
comment
в соответствии с моим требованием я хочу добавить ключ «1» дважды или трижды с разными значениями для каждого ключа «1». например: $ hashtable = @ {1 = 'host1'; 2 = «хост2», «хост4»; 1 = 'host3'} - person Django Unchained; 29.10.2020
comment
@DjangoUnchained да? Ничто не мешает вам сделать это, используя описанный выше подход. - person Mathias R. Jessen; 29.10.2020

Чтобы дополнить ответ @Matthias:
Вы не можете иметь повторяющиеся ключи в хеш-таблица. Это сделано намеренно. Хеш-таблицы содержат список уникальных ключей, основанный на алгоритме двоичного поиска, где каждый ключ связан с конкретный объект (ценность).

Есть два обходных пути:

1. добавить массив значений к определенному ключу хеш-таблицы:

$Keys = 1,2,2,3
$Values = 'a'..'d'
$HashTable = @{}
$i = 0
foreach($key in $Keys){ [array]$HashTable[$Key] += $Values[$i++] }

Iterating
The disadvantage is that you lose the order of the items (regardless if you use an ordered dictionary simply because some values share a single key).

Foreach ($Key in $Hashtable.Keys) {
    Foreach ($Value in @($Hashtable[$Key])) {
        Write-Host $Key '=' $Value
    }
}

3 = d
2 = b
2 = c
1 = a

Searching
The advantage is that the items are binary indexed and therefor quickly found.

$SearchKey = 2
Foreach ($Value in @($Hashtable[$SearchKey])) {
    Write-Host $SearchKey '=' $Value
}

2 = b
2 = c

2. или вы можете создать список (массив) хэш-таблиц (пары ключевых значений)

$Keys = 1,2,2,3
$Values = 'a'..'d'
$i = 0
$KeyValuePairs = foreach($key in $keys){ @{ $Key = $Values[$i++] } }

Итерация
Преимущество состоит в том, что элементы останутся в порядке.
(Обратите внимание, что вы должны вызвать _ 7_ дважды)

$KeyValuePairs.GetEnumerator().GetEnumerator() | Foreach-Object {
    Write-Host $_.Key '=' $_.Value
}

1 = a
2 = b
2 = c
3 = d

Searching
The disadvantage is that searching for the items is slower and little more comprehensive.

$SearchKey = 2
$KeyValuePairs.GetEnumerator().GetEnumerator() | 
    Where-Object Key -eq $SearchKey | Foreach-Object {
    Write-Host $_.Key '=' $_.Value
}

2 = b
2 = c
person iRon    schedule 29.10.2020
comment
Что, если я хочу добавить 3 значения к ключу (3), так и должно быть. например: для ключа 2 = 2 будут добавлены значения, а для ключа 4 = 4 будут добавлены значения - person Django Unchained; 05.11.2020
comment
Это уже показано в ответе выше. Чтобы сделать это более ясным; Я обновил его другими значениями (вы можете изменить это на 'a'..'z', если хотите поиграть с другими парами "ключ-значение"). В любом случае, если он по-прежнему не отвечает на то, что вы ищете, я рекомендую вам (повторно) создать вопрос с минимальным воспроизводимый пример (как в приведенных выше примерах) и ожидаемый результат (список пар ключ-значение), поскольку я либо все еще не понимаю вас, либо вы начинаете противоречить себе. - person iRon; 05.11.2020

Я делаю это в отдельном ответе, поскольку ваша новая переопределенная цель более конкретна, чем появился первоначальный вопрос. Вместо этого каждый ответ должен быть назначен соответствующему подномеру.

Скрипт:

$podnumbers = @(1,3,1)
$Inputs = 1,2,4,6,3
$c = 0
$podarray = foreach ($pd in $podnumbers) {
    $podinfo = @{}
    for($i=0; $i -lt $pd; $i = $i+1) {
        # $pod = Read-Host -Prompt "Assign the pod numbers for",$esxarray[$buffer]
        [array]$podinfo[$pd] += $Inputs[$c++]
    }
    $podinfo
}
$podarray

Вывод:

Name                           Value
----                           -----
1                              {1}
3                              {2, 4, 6}
1                              {3}
person iRon    schedule 05.11.2020
comment
спасибо iRon, я пробовал вышеуказанный скрипт, но запись-вывод $ podarray была пуста в cli - person Django Unchained; 05.11.2020
comment
Я снова протестировал, и для меня приведенный выше пример работает как с Windows PowerShell 5.1, так и с PowerShell Core 7. - person iRon; 05.11.2020
comment
$ podinfo вне внутреннего цикла for, то есть} $ podinfo} он там нужен? - person Django Unchained; 06.11.2020
comment
Просто $podinfo похоже на _ 2_ он записывает данные в конвейер и в конечном итоге отображает их. Это означает, что вы можете оставить его (если вы не хотите отображать результаты) или подумать о том, чтобы передать его другому командлету (но это совершенно другой вопрос). Теперь это работает? Отвечает ли он на вопрос? - person iRon; 06.11.2020
comment
он не выдавал ошибки и не отображал результаты для Write-Output $ podarray - person Django Unchained; 06.11.2020
comment
Я собираюсь сдаться: если вы вставите содержимое в Сценарий, в IDE или в новую консоль PowerShell, вы должны увидеть содержимое, как показано в разделе Вывод. Это доказывает, что $podarray содержит запрошенную информацию. - person iRon; 06.11.2020