Reputation: 333
I feel like my Delphi background is destroying my ability to figure this out. I'm trying to create an empty array (no data, just structure) in Powershell where each item has two properties. The end result would look something like this:
$WIP[0].signature = 'data'
$WIP[0].PID = 'data'
# other fake stuff in between
Write-host "Item 43 has signature: " $WIP[43].signature
For some reason, I'm roadblocking on every attempt to create what should be simple to do. Thoughts?
I know some people do similar to the following, but this isn't as flexible as I'd like:
$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
This requires the values to be present for all three members when creating each $object. I was thinking the init would look more along the lines of (pseudocode):
$MyRecord = {
Signature as string
PID as integer
}
$RecArray = array of $MyRecord
That's notably a bad mashup of Delphi and Powershell. But would create a fully structured array, addressable as noted up top.
Upvotes: 0
Views: 6588
Reputation: 437823
A PSv5+ solution that uses a PS class and a generic list ([System.Collections.Generic.List[]]
) to store the instances (loosely speaking, an array that can grow efficiently).
# 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
The above yields:
Signature PID
--------- ---
sig1 666
sig2 667
As for removing objects from the list:
To remove by index, use .RemoveAt()
; an out-of-range index throws an error:
$RecList.RemoveAt(1)
To remove by object already stored in the list, use .Remove()
.
Note that the [bool]
return value indicates whether the value was
actually removed (if the object wasn't in the list, the operation is
a no-op and $False
is returned)
$actuallyRemoved = $RecList.Remove($newRec)
For details, see the docs.
Upvotes: 4
Reputation: 2943
You can use a hashtable with indices as keys, and your hashtable as values. It's pretty easy to work with.
$WIP = @{
0 = @{
signature = 'signature 0'
PID = 'PID 0'
}
1 = @{
signature = 'signature 1'
PID = 'PID 1'
}
}
You can add any index you want.
$WIP[12] = @{
signature = "signature 12"
PID = "PID 12"
}
$WIP[12].PID
# PID 12
You can initialize both, any, or none.
$WIP[76] = @{
signature = "signature 76"
}
$WIP[76].signature
# signature 76
$WIP[76].PID
# $null
Count gives you number of "active" elements.
$WIP.Count
# 4
Upvotes: 0
Reputation: 37730
There is no real difference between this an what you have already been shown but I think this gives you what you are asking for (even though it is not the powershelly way to do things).
$object = "New-Object PSCustomObject -Property @{'Name' = ''; 'Age' = [int]}"
$array = 1..100 | %{Invoke-Expression $object}
$array[0].Name = 'Joe'
$array[0].Age = 12
$array[0]
Upvotes: 0
Reputation: 857
What exactly do you mean by "Dynamic"?
$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'
}
}
)
Or you can manually add objects like so
$array = @()
# Later in code
$array += New-object psobject @{
Signature = 'data'
PID = 'data'
}
Then you can access each item like so:
$array[1].Signature
$array[1].PID
Upvotes: 0
Reputation: 671
So here's working example of how You can get something like this working:
$list=@()
1..100|foreach-object{
$obj=""|select signature,pid
$obj.signature="$_ signature"
$obj.pid="$_ PID"
$list+=$obj
}
With the object created this way - You can do $list[43].signature
and it does work.
Upvotes: 0
Reputation: 4168
You want to create a custom object.
You create an object that has all the properties you need. Then you create a collection, and you stuff instances of your new object into the collection. Here's an example:
$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
You'd need to execute the New-Object and Add-Member statements for each object you're creating.
Upvotes: 0