Siento que mi experiencia en Delphi está destruyendo mi capacidad para resolver esto. Estoy tratando de crear una matriz vacía (sin datos, solo estructura) en Powershell donde cada elemento tiene dos propiedades. El resultado final se vería así:

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

Por alguna razón, estoy bloqueando cada intento de crear lo que debería ser simple de hacer. Pensamientos?

Actualización para responder preguntas

Sé que algunas personas hacen lo siguiente, pero esto no es tan flexible como me gustaría:

$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

Esto requiere que los valores estén presentes para los tres miembros al crear cada objeto $. Estaba pensando que el init se vería más en la línea de (pseudocódigo):

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

Eso es notablemente un mal mashup de Delphi y Powershell. Pero crearía una matriz completamente estructurada, direccionable como se indica arriba.

0
SaintFrag 2 mar. 2018 a las 18:19

6 respuestas

La mejor respuesta

Una solución PSv5 + que utiliza una class de PS y una lista genérica ([System.Collections.Generic.List[]]) para almacenar las instancias (en términos generales, un matriz que puede crecer de manera eficiente).

# 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

Los rendimientos anteriores:

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

En cuanto a eliminar objetos de la lista:

  • Para eliminar por índice , use .RemoveAt(); un índice fuera de rango arroja un error:

    • $RecList.RemoveAt(1)
  • Para eliminar por objeto ya almacenado en la lista, use .Remove().
    Tenga en cuenta que el valor de retorno [bool] indica si el valor era realmente eliminado (si el objeto no estaba en la lista, la operación es un no-op y se devuelve $False)

    • $actuallyRemoved = $RecList.Remove($newRec)

Para obtener detalles, consulte los documentos.

4
mklement0 2 mar. 2018 a las 17:17

¿Qué quiere decir exactamente con "dinámico"?

$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'
        }
    }
)

O puede agregar objetos manualmente de esta manera

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

Luego puede acceder a cada elemento de esta manera:

$array[1].Signature
$array[1].PID
0
HeedfulCrayon 2 mar. 2018 a las 16:03

Puede usar una tabla hash con índices como claves y su tabla hash como valores. Es bastante fácil trabajar con él.

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

Puede agregar cualquier índice que desee.

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

$WIP[12].PID
# PID 12

Puede inicializar ambos, cualquiera o ninguno.

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

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

El recuento le da un número de elementos "activos".

$WIP.Count
# 4
0
Božo Stojković 2 mar. 2018 a las 16:25

No hay una diferencia real entre esto y lo que ya se le ha mostrado, pero creo que esto le da lo que está pidiendo (a pesar de que no es la forma poderosa de hacer las cosas).

$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 mar. 2018 a las 16:16

Así que aquí hay un ejemplo práctico de cómo puedes hacer que algo como esto funcione:

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

Con el objeto creado de esta manera, puede hacer $list[43].signature y funciona.

0
Tomek 2 mar. 2018 a las 15:44

Desea crear un objeto personalizado.

Crea un objeto que tiene todas las propiedades que necesita. Luego, crea una colección y agrega instancias de su nuevo objeto a la colección. Aquí hay un ejemplo:

$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

Tendrá que ejecutar las declaraciones New-Object y Add-Member para cada objeto que esté creando.

0
Adam 2 mar. 2018 a las 15:40