Как добавить хеш-таблицу в многомерный массив? Невозможно присвоить значения через перечисление членов
У меня проблемы с добавлением хеш-таблиц в многомерный массив. Я закодировал следующее:
$Data = @{BIBs = @(
@{$BIB = @{BIBName=$BIBName},
@{Standort = $Standort},
@{Bücher = @(
@{BuchName = $BuchName;
Autor = $Autor
})
}}
)}
Этот код работает и создает вывод, который я сохраняю в JSON:
{
"BIBs": [
{
"BIB1": [
{
"BIBName": "123"
},
{
"Standort": "123"
},
{
"Bücher": [
{
"Autor": "123",
"BuchName": "123"
}
]
}
]
},
{
"BIB2": [
{
"BIBname": "345"
},
{
"Standort": "345"
},
{
"Bücher": [
{
"Autor": "345",
"Buchname": "345"
}
]
}
]
}
]
}
У меня есть дополнительный код, который добавляет еще одну хеш-таблицу в массив "BIB", как вы можете видеть.
$jsonfile = "C:\Skripte\bibV2-1000.json"
$Data = Get-Content $jsonfile | ConvertFrom-Json
$Data.BIBs += New-Object -TypeName PSObject -Property @{
$BIB = @{BIBname=$BIBName}, @{Standort=$Standort},
@{Bücher = @(@{Buchname=$BuchName;Autor=$Autor})}
}
Когда вывод такой, как указано выше, я не могу добавить еще одну хеш-таблицу в "Bücher". Я проверил тип "Бюхер" с
$data.BIBs.BIB1.Bücher.GetType()
и это на самом деле массив:
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object [] System.Array
Я старался
$Data.BIBs.BIB1.Bücher += @{Person="Max";Alter="35"}
добавить новую хеш-таблицу, как я сделал с "BIB2", но я получаю ошибку:
Свойство 'Bücher' не может быть найдено на этом объекте. Убедитесь, что свойство существует и может быть установлен. В строке:5 символов:1 + $data.BIBs.BIB1.Bücher += @{Motor="asdf";pers="345"} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ + CategoryInfo: InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId: PropertyAssignmentException
Вы знаете, как я добавляю @{Person="Max";Alter="35"}
в "Бюхер"?
1 ответ
ТЛ; др
Установка значения ключа / свойства с помощью перечисления членов не поддерживается (см. Ниже).
Вместо этого вы должны получить конкретный объект, чей .Bücher
свойство, которое вы хотите явно изменить:
($Data.BIBs.BIB1 | ? Bücher).Bücher += @{ BuchName='neues Buch'; Autor='Johann Doe' }
Примечание: это предполагает, что:
* только один элемент массива $Data.BIBs.BIB1
имеет .Bücher
свойство (ключ)
* что, если свойство / ключ существует, оно непусто и, следовательно, является "правдивым" в булевом контексте, таком как выражение, переданное в ?
( Where-Object
); как перечисление членов, это упрощенное Where-Object
синтаксис - ? Bücher
вместо ? { $_.Bücher }
- это функция PSv3+, называемая оператором сравнения.
Mathias R. Jessen предоставил ключевой указатель в комментариях к вопросу:
PowerShell имеет преднамеренную асимметрию относительно точечной нотации в свойствах с коллекционными значениями для получения значений по сравнению с настройками значений.
При получении PSv3+ применяет перечисление членов, которое, в двух словах, позволяет получить доступ к свойству коллекции и неявно получить значение этого свойства из каждого элемента в этой коллекции, а результаты собираются в массиве.
При настройке перечисление членов не применяется; обоснование заключается в том, что риск непреднамеренного изменения данных слишком высок - см. эту проблему GitHub и, в частности, этот комментарий одного из основных членов команды PS.
К сожалению, текущее сообщение об ошибке не говорит вам об этом.
Это связано с тем, что при попытке установить свойство на уровне коллекции, свойство ищется только непосредственно в коллекции (а не в ее элементах), где оно (обычно) не существует.
Давайте посмотрим на упрощенный пример:
$data = @{ # a hashtable
a = ( # array of hashtables
@{ b1 = 'b1' },
@{ b2 = 'b2' },
@{ b3 =
@{ b31 = 'b31' }, @{ b32 = 'b32' } # array of hashtables
}
)
}
При получении все отлично работает
PS> $data.a.b3
Name Value
---- -----
b31 b31
b32 b32
Даже если $data.a
является [object[]]
массив, объект (хеш-таблица) со свойством .b3
был найден среди его элементов, и этот объект .b3
значение выводится.
Это перечисление членов в действии (хотя более типичное использование - это свойство существовать во всех элементах массива и отдельные значения, собираемые в [object[]]
массив).
При установке PowerShell отказывается от перечисления членов и, следовательно, безуспешно ищет .b3
собственность только непосредственно на [object[]]
экземпляр, который является $data.a
и, конечно же, массивы не имеют .b3
имущество:
PS> $data.a.b3 += @{ b33 = 'b33' } # Try to add an element; !! FAILS
The property 'b3' cannot be found on this object.
Verify that the property exists and can be set.
...