I'm having a little trouble finding the index of a hashtable in an array. I create a JSON with this code:
$start = {
Clear-Host
$BIB = Read-Host 'Bibliothek'
$BIBName = Read-Host 'Bibliothek Name'
$Standort = Read-Host 'Bibliothek Standort'
$Autor = Read-Host 'Buchautor'
$BuchName = Read-Host 'Buchname'
$jsonfile = "C:\Skripte\bibV2-1000.xml"
if(![System.IO.File]::Exists($jsonfile)){
$Data = @{BIBs = @(
@{$BIB = @{BIBName=$BIBName},
@{Standort = $Standort},
@{Bücher = @(
@{BuchName = $BuchName;
Autor = $Autor})
}}
)}
ConvertTo-Json -Depth 50 -InputObject $Data | Add-Content $jsonfile
.$continue
} else {
$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})
}
}
ConvertTo-Json -Depth 50 -InputObject $Data | Out-File $jsonfile}
.$continue
}
$continue = {
Write-Host ""
Write-Host "Was wollen Sie machen?"
Write-Host "(1) Eine weitere Bibliothek hinzufügen"
Write-Host "(2) Einer Bibliothek neue Bücher hinzufügen"
Write-Host "(E) Script beenden"
If (($read = Read-Host ) -eq "1") {
&$start} else {
if (($read) -eq "2") {
. C:\Skripte\büc.ps1 } else {
if (($read) -eq "E") {
exit} else {
Write-Host "+++ FALSCHE EINGABE! Bitte wählen Sie (1) oder (2) für die entsprechende Aktion +++"
.$continue
}
}
}
}
&$start
The output is as follows:
{
"BIBs": [{
"BIB1": [{
"BIBName": "123"
},
{
"Standort": "123"
},
{
"Bücher": [{
"Autor": "123",
"BuchName": "123"
}]
}
]
},
{
"BIB2": [{
"BIBname": "345"
},
{
"Standort": "345"
},
{
"Bücher": [{
"Autor": "345",
"Buchname": "345"
}]
}
]
}
]
}
Now I want to find out the index of "BIB1". I already tried the IndexOf()-Method which should create the output "0" but it gives me "-1" instead, because it can't find the value. How can I get the index of "BIB1"?
Judging by your earlier question , you're attempting to get the index of a specific object so you can access it via its containing array. However, you can do this more directly: $objOfInterest = $Data.BIBs | ? BIB1
$objOfInterest = $Data.BIBs | ? BIB1
$objOfInterest = $Data.BIBs | ? BIB1
- see my answer to your earlier question for details.
You need to iterate over the array elements of $Data.BIBs
, which - on reading your serialized-to-a-file-as-JSON hashtables back in with ConvertFrom-Json
- are custom objects (as Ansgar correctly points out; they are instances of [System.Management.Automation.PSCustomObject]
), and check each for the presence of property 'BIB1'
:
(In a hashtable, you'd check for the presence of key 'BIB1'
with .ContainsKey('BIB1')
)
To test the existence of an object property , you need reflection , which is most easily - but somewhat obscurely - achieved via the hidden .PSObject
property, as demonstrated in Ansgar Wiechers' more elegant solution .
However, given that the properties of interest have nonempty values, we can infer from the presence of a nonempty value that a given property exists, using implicit Boolean (logic): $obj.'BIB1'
by default returns $null
if there is no BIB1
property, which is "falsy" in a Boolean context such as an if
conditional; conversely, any nonempty value is "truthy":
$propName = 'BIB1'
$i = $ndx = -1
foreach ($obj in $Data.BIBs) {
++$i
if ($obj.$propName) { $ndx = $i; break}
}
$ndx # $ndx now contains the index of the target object or -1 if there was no match
$Date.BIBs
is an array of custom objects, not hashtables (since you wrote your original data to a JSON file and then converted that back), so you need something like this:
$arr = $Data.BIBs | ForEach-Object { $_.PSObject.Properties.Name }
$arr.IndexOf('BIB1') # returns 0
$arr.IndexOf('BIB2') # returns 1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.