Я чувствую, что мой опыт Delphi разрушает мою способность понять это. Я пытаюсь создать пустой массив (без данных, просто структура) в Powershell, где каждый элемент имеет два свойства. Конечный результат будет выглядеть примерно так:

$WIP[0].signature = 'data'
$WIP[0].PID = 'data'
# other fake stuff in between
Write-host "Item 43 has signature:  " $WIP[43].signature

По какой-то причине я блокирую каждую попытку создать то, что должно быть просто сделать. Мысли ?

Обновление для ответа на вопросы

Я знаю, что некоторые люди делают подобное, но это не так гибко, как хотелось бы:

$array = @()
$object = New-Object -TypeName PSObject
$object | Add-Member -Name 'Name' -MemberType Noteproperty -Value 'Joe'
$object | Add-Member -Name 'Age' -MemberType Noteproperty -Value 32
$object | Add-Member -Name 'Info' -MemberType Noteproperty -Value 'something about him'
$array += $object

Это требует наличия значений для всех трех членов при создании каждого объекта $. Я думал, что инициализация будет выглядеть по-другому (псевдокод):

$MyRecord = {
    Signature as string
    PID as integer
}
$RecArray = array of $MyRecord

Это особенно плохое сочетание Delphi и Powershell. Но создаст полностью структурированный массив, адресуемый, как отмечено выше.

0
SaintFrag 2 Мар 2018 в 18:19

6 ответов

Лучший ответ

Решение PSv5 + , в котором используется класс PS и общий список ([System.Collections.Generic.List[]]) для хранения экземпляров (условно говоря, массив, который может расти эффективно).

# Your custom type.
class MyRecord {
    [string] $Signature
    [int] $PID
}

# If you want a list that can grow efficiently,
# use [System.Collections.Generic.List[]]
$RecList = [System.Collections.Generic.List[MyRecord]]::new()

# Add a new instance...
$RecList.Add([MyRecord]::new())

# ... and initialize it.
$RecList[0].Signature = 'sig1'
$RecList[0].Pid = 666

# ... or initialize it first, and then add it.
# Note the use of a cast from a hashtable with the property values.
$newRec = [MyRecord] @{ Signature = 'sig2'; PID = 667}
$RecList.Add($newRec)

# Output the list
$RecList

Вышеуказанные выходы:

Signature PID
--------- ---
sig1      666
sig2      667

Что касается удаления объектов из списка:

  • Чтобы удалить с помощью index , используйте .RemoveAt(); индекс вне допустимого диапазона выдает ошибку:

      < Литий> $RecList.RemoveAt(1)
  • Чтобы удалить объект , уже сохраненный в списке, используйте .Remove().
    Обратите внимание, что возвращаемое значение [bool] указывает, было ли это значение фактически удален (если объект не был в списке, операция no-op и $False возвращается)

      < Литий> $actuallyRemoved = $RecList.Remove($newRec)

Подробнее см. В документы. ,

4
mklement0 2 Мар 2018 в 17:17

Что именно вы подразумеваете под «Динамик»?

$array = @(
    # Some type of loop to create multiple items foreach/for/while/dowhile
    foreach ($item in $collection) {
        New-Object psobject -Property @{
            Signature = 'data'
            PID = 'data'
        }
    }
)

Или вы можете вручную добавлять объекты, как так

$array = @()
# Later in code
$array += New-object psobject @{
    Signature = 'data'
    PID = 'data'
}

Затем вы можете получить доступ к каждому элементу следующим образом:

$array[1].Signature
$array[1].PID
0
HeedfulCrayon 2 Мар 2018 в 16:03

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

$WIP = @{
    0 = @{
        signature = 'signature 0'
        PID = 'PID 0'
    }
    1 = @{
        signature = 'signature 1'
        PID = 'PID 1'
    }
}

Вы можете добавить любой индекс, который вы хотите.

$WIP[12] = @{
    signature = "signature 12"
    PID = "PID 12"
}

$WIP[12].PID
# PID 12

Вы можете инициализировать оба, любой или ни одного.

$WIP[76] = @{
    signature = "signature 76"
}

$WIP[76].signature
# signature 76
$WIP[76].PID
# $null

Count дает вам количество «активных» элементов.

$WIP.Count
# 4
0
Božo Stojković 2 Мар 2018 в 16:25

Нет реальной разницы между этим и тем, что вам уже было показано, но я думаю, что это дает вам то, о чем вы просите (даже если это не самый мощный способ сделать что-то).

$object = "New-Object PSCustomObject -Property @{'Name' = ''; 'Age' = [int]}"
$array = 1..100 | %{Invoke-Expression $object}
$array[0].Name = 'Joe'
$array[0].Age = 12 
$array[0]
0
EBGreen 2 Мар 2018 в 16:16

Итак, вот рабочий пример того, как Вы можете получить что-то подобное:

 $list=@()
 1..100|foreach-object{
 $obj=""|select signature,pid
 $obj.signature="$_ signature"
 $obj.pid="$_ PID"
 $list+=$obj
}

С объектом, созданным таким образом - Вы можете сделать $list[43].signature, и он работает.

0
Tomek 2 Мар 2018 в 15:44

Вы хотите создать пользовательский объект.

Вы создаете объект, который обладает всеми необходимыми вам свойствами. Затем вы создаете коллекцию и помещаете экземпляры вашего нового объекта в коллекцию. Вот пример:

$WIP = @()
$o = New-Object –TypeName PSObject
Add-Member -InputObject $o –MemberType NoteProperty –Name signature –Value 'foo'
Add-Member -InputObject $o –MemberType NoteProperty –Name data –Value 'bar'
$WIP += $o

$WIP[0].signature
$WIP[0].data

Вам нужно будет выполнить операторы New-Object и Add-Member для каждого создаваемого вами объекта.

0
Adam 2 Мар 2018 в 15:40