Custom Objects within an Array explanation

This topic contains 2 replies, has 3 voices, and was last updated by Profile photo of Rob Simmers Rob Simmers 1 month, 1 week ago.

  • Author
    Posts
  • #64653
    Profile photo of Brian Clanton
    Brian Clanton
    Participant

    I read this article in Powershell online magazine and I am having a hard time getting my mind wrapped around it as to what it means.

    It gives the following example code:

    $groups = 'Group1', 'Group2'
    $users = 'User1', 'User2'
     
    $objectCollection=@()
     
    $object = New-Object PSObject
    Add-Member -InputObject $object -MemberType NoteProperty -Name Group -Value ""
    Add-Member -InputObject $object -MemberType NoteProperty -Name User -Value ""
     
    $groups | ForEach-Object {
    $groupCurrent = $_
     
       $users | ForEach-Object {
          $userCurrent = $_
             $object.Group = $groupCurrent
             $object.User = $userCurrent
     
             $objectCollection += $object
        }
    }
     
    $objectCollection
    

    It shows the output as this:

    Group  User 
    -----  ---- 
    Group2 User2
    Group2 User2
    Group2 User2
    Group2 User2
    

    It then explains why we are getting this output. The is the paragraph I am having a problem understanding as well as the link to the article.

    We assign the information to the object and add it to the collection, but we still use the same object. When we added it to the collection we added just a 'reference' to the object, not the object itself. What we ended up with was just four 'shortcuts' to the same object.
    
    From  
    
    

    I don't understand they mean by 'reference to the object and not the object itself. When you are using the using the statement,
    $object.Group = $groupCurrent and $object.User = $userCurrent, are you not adding those values to that object? I don't understand what they mean by 'reference'.

  • #64771
    Profile photo of Don Jones
    Don Jones
    Keymaster

    This gets into some fairly esoteric programming concepts, specifically, ByValue and ByReference.

    When you assign something ByValue, you're passing the _contents of whatever it is_. So if I have $a=4, and I set $b=$a ByValue, I can then set $a=5 but $b will still be 4.

    Conversely, setting something ByReference just passes a _reference_ to, basically, the same memory location. So if $a=4 and I set $b=$a, changing $a=5 will also set $b to 5, because $a and $b are really both pointers to the same memory location.

    Add-Member works that way with its -InputObject parameter. It doesn't create a new object having whatever properties you added; it adds the property to the original copy, so whatever variable was referencing that copy ($object in this case) will now reference the updated object.

  • #64803
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    As a side note, that is an old example of creating an object in Powershell and the results that you posted are incorrect (not the intention of the code or example, I'm guessing). This should be much easier to implement and read:

    $groups = 'Group1', 'Group2'
    $users = 'User1', 'User2'
     
    #Collect all results from the for loops and place them in $objectCollection
    $objectCollection =  foreach ($group in $groups)  {
     
        foreach ($user in $users)  {
            New-Object -TypeName PSObject -Property @{
                Group = $group
                User  = $user
            }
        }
    }
     
    $objectCollection
    

    Output:

    User  Group 
    ----  ----- 
    User1 Group1
    User2 Group1
    User1 Group2
    User2 Group2
    

You must be logged in to reply to this topic.