5

I've created a class containing simple values:

Class Volumes {
  [String]$ID
  [String]$Name
}

Now I'd like to create another class that contains an array of Volume Objects.

Something like:

Class Storage {
  [String]$Name
  [String]$IP
  [Array]@Volumes  # <- I know this is wrong, but I don't know how to do it
}

Thus, 2 questions:

  • How to create an array of objects inside the class ?
  • How to access / modify the array members, once I've built a new Object of class Storage ?

Thx in advance, Ralf.

0

1 Answer 1

5

The below example should get you going for now!

You define an array of objects by simply putting [] after the type, so Volume[]

At the bottom of the snippet are 2 examples that show how to access the volumes data too.

Class Volume {
  [String]$ID
  [String]$Name 
}

Class Storage {
  [String]$Name
  [String]$IP
  [Volume[]]$Volumes 
}

# Create a volume object
$volume1 = New-Object Volume
$volume1.ID = '1'
$volume1.Name = 'Data'

# Create another volume object
$volume2 = New-Object Volume
$volume2.ID = '2'
$volume2.Name = 'Log'

# Create a storage object
$storage = New-Object Storage
$storage.Name = 'SomeStorage'
$storage.IP = '0.0.0.0'

# Add the volume objects
$storage.Volumes += $volume1
$storage.Volumes += $volume2

# access a volume by name or index
$storage.Volumes | Where-Object {$_.Name -eq 'Data'}
$storage.Volumes[0]

Educational N.B by zett42 and santiago squarzon

The array is inefficient when you add many elements one-by-one. You might want to have a look at ArrayList / List types.

You could instead use [List[Volume]]$Volumes = [List[Volume]]::new() in your Storage class. Make sure to put a using namespace System.Collections.Generic at the top of your script. Then when you add volumes do $storage.Volumes.Add($volume1)


I did some performance testing for this, i added 10_000 volumes to the object. The array took 9.3 seconds, and the list took 0.93 seconds, a 10 fold performance improvement.

Array - Quadratic - O(N²)

+= recreates the entire array, it copies the old contents into a new array along with the new element.

ArrayList - Constant - O(1)

ArrayList has O(n) time complexity for arbitrary indices of add/remove, but O(1) for the operation at the end of the list.

using namespace System.Collections.Generic

Class Volume {
  [String]$ID
  [String]$Name 
}

Class Storage {
  [String]$Name
  [String]$IP
  [List[Volume]]$Volumes = [List[Volume]]::new()
}

# Create volume objects
$volume1 = New-Object Volume
$volume1.ID = '1'
$volume1.Name = 'Data'

# Create another volume object
$volume2 = New-Object Volume
$volume2.ID = '2'
$volume2.Name = 'Log'

# Create a storage object
$storage = New-Object Storage
$storage.Name = 'SomeStorage'
$storage.IP = '0.0.0.0'

# Add the volume objects
$storage.Volumes.Add($volume1)
$storage.Volumes.Add($volume2)

# access a volume by name or index
$storage.Volumes | Where-Object {$_.Name -eq 'Data'}
$storage.Volumes[0]
Sign up to request clarification or add additional context in comments.

2 Comments

Works like a charm, exactly what I was looking for. Thanks so much
Thanks zett42 and santiago squarzon, I modified my Script as suggested ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.