【问题标题】:How to get index of hashtable in array?如何获取数组中哈希表的索引?
【发布时间】:2018-08-29 04:53:27
【问题描述】:

我在查找数组中哈希表的索引时遇到了一些麻烦。我用这段代码创建了一个 JSON:

$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

输出如下:

{
    "BIBs": [{
        "BIB1": [{
            "BIBName": "123"
        },
            {
                "Standort": "123"
            },
            {
                "Bücher": [{
                    "Autor": "123",
                    "BuchName": "123"
                }]
            }
        ]
    },
        {
            "BIB2": [{
                "BIBname": "345"
            },
                {
                    "Standort": "345"
                },
                {
                    "Bücher": [{
                        "Autor": "345",
                        "Buchname": "345"
                    }]
                }
            ]
        }
    ]
}

现在我想找出“BIB1”的索引。我已经尝试过 IndexOf() 方法,它应该创建输出“0”,但它给了我“-1”,因为它找不到值。如何获取“BIB1”的索引?

【问题讨论】:

  • 你能展示你正在使用的对象吗?这看起来像一个 json 对象
  • 请使用此信息编辑您的问题。在 cmets 中读取代码很糟糕......
  • 所以。关于 ConvertTo-Json 的一件事是它不会生成“Json 对象”。它只是创建一个 Json 格式的字符串。如果您想要一个可以轻松操作和查看的结构化数据对象,我建议您将其保留为数组和哈希的哈希,就像您在转换之前一样,或者将其转换为 XML。
  • 我已经试过了,没有转成json,但是IndexOf()的输出还是“-1”
  • 已经尝试过什么?已经试过了怎么办?你试过什么代码?

标签: arrays powershell hashtable


【解决方案1】:

根据您的earlier question 判断,您正在尝试获取特定对象的索引,以便您可以通过其包含的数组访问它。但是,您可以更直接地执行此操作:$objOfInterest = $Data.BIBs | ? BIB1 - 有关详细信息,请参阅我的 answer to your earlier question

您需要遍历 $Data.BIBs 的数组元素,其中 - 在使用 ConvertFrom-Json 读取您的序列化到文件作为 JSON 哈希表时 - 是 自定义对象 (正如 Ansgar 正确指出的那样;它们是 [System.Management.Automation.PSCustomObject] 的实例),并检查每个是否存在 property 'BIB1':

但是,考虑到感兴趣的属性具有非空值,我们可以推断使用隐式布尔值(逻辑)从存在的非空值中推断出给定属性的存在:$obj.'BIB1' 默认情况下如果没有 BIB1 属性,则返回 $null,这在诸如 if 条件的布尔上下文中是“假的”;相反,任何非空值都是“真实的”:

$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

【讨论】:

    【解决方案2】:

    $Date.BIBs 是一个自定义对象数组,而不是哈希表(因为您将原始数据写入 JSON 文件,然后将其转换回来),因此您需要这样的东西:

    $arr = $Data.BIBs | ForEach-Object { $_.PSObject.Properties.Name }
    $arr.IndexOf('BIB1')  # returns 0
    $arr.IndexOf('BIB2')  # returns 1
    

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 2013-01-02
      • 2014-05-18
      • 2016-03-02
      • 2013-06-27
      • 2011-04-16
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      相关资源
      最近更新 更多