Reputation: 11
I am trying to create an array of usernames with a list of eventIDs that I can update and add new users i.e ( ('user1', '23,4523'), ('user2', '5670,2300'), ('user3','321,1299') )
When I initialize the array with the first user and update that user with additional events, I get the expected results.
PS> $usrProfile
user1
4567,1234
When I add a new user ('user2', '6688') instead of getting an array count of '2', it is still '1' and the array returns array object details..... Ok, so I think that works
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {user1, 4567,1234,2300}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {user2, 6688}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
.... then the wheels come off when I update 'user2', the original 'user1' record disappears and 'user2' has the updated value, but loses the initial value. Also, initially $item[0] in the foreach loop returns the username, after adding a new user $item[0] returns object info..
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {System.Object[], System.Object[]}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {user2, 7009}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
These are commands...
$usrProfile = @( )
$usrProfile = ,(funcUpdateUserProfile "user1" 4567 $usrProfile)
$usrProfile.count
$usrProfile = ,(funcUpdateUserProfile "user1" 1234 $usrProfile)
$usrProfile.count
$usrProfile = ,(funcUpdateUserProfile "user1" 2300 $usrProfile)
$usrProfile.count
$usrProfile = ,(funcUpdateUserProfile "user2" 6688 $usrProfile)
$usrProfile.count
$usrProfile = ,(funcUpdateUserProfile "user2" 7009 $usrProfile)
$usrProfile.count
$usrProfile
I have spent several days on this and am making no progress.... thanks and gratitude in advance for anyone who can spot what I'm doing wrong.....here is the code......
function funcUpdateUserProfile ($userName, $tmpINTEventID, $tmpUserProfileArray) {
$Global:updUserProfileArray = @()
$initFlag = $false
$UpdUserFlag = $false
$tmpEventStr = $tmpINTEventID.tostring()
if ($tmpUserProfileArray.length -eq 0 ) {
$updUserProfileArray += ,( ("$userName" , "$tmpEventStr") )
$initFlag = $true
}else {
ForEach ($item in $tmpUserProfileArray) {
if ( ($item[0].toString()) -like "*$userName*" ) {
$UpdUserFlag = $true
$user = $item[0].toString()
$tmpOldStr = $item[1].toString()
$updStr = $tmpOldStr +','+ $tmpEventStr
$updUserProfileArray += ,( ($user, ("$updStr")) )
}elseif ( !(($item[0].toString()) -like "*$userName*") ) {
$user = $item[0].toString()
$tmpOldStr = $item[1].toString()
$updUserProfileArray += ,( ($user, ("$tmpOldStr")) )
}#End if Else
}#End ForEach
}#end IfElse
if ( ($initFlag -eq $false ) -AND ($UpdUserFlag -eq $false) ) {
$updUserProfileArray += ,( ($userName, "$tmpEventStr") )
}
return $updUserProfileArray
}
Upvotes: 1
Views: 247
Reputation: 16126
If I am following you, is this what you were after with your use case.
# If I am following you, is this what you were after with your use case.
# Initial multidementonal array
[System.Collections.ArrayList]$ScoreDetails = @()
$ScoreDetails = @(
@('Player001', '200'),
@('Player002', '199')
)
# Arrray count
$ScoreDetails.Count
# Results
<#
2
#>
# Array details
$ScoreDetails |
Select-Object -Property '*'
# Results
<#
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player001, 200}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player002, 199}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
#>
# Ask for new entry
'Enter NEXT player score details'
$name = Read-Host 'Name'
$score = Read-host 'Score'
# Results
<#
Enter NEXT player score details
Name: Player003
Score: 300
#>
<#
Comma, to tell PowerShell to add a new row the multidimensional array
#>
$ScoreDetails += ,(@($name,$score))
# Arrray count
$ScoreDetails.Count
# Results
<#
3
#>
# Update the array
for(
$OuterLoop = 0
$OuterLoop -lt 3
$OuterLoop ++
)
{
for(
$InnerLoop = 0
$InnerLoop -lt 2
$InnerLoop ++
)
{
"The value of [$OuterLoop][$InnerLoop] ---> " +
$ScoreDetails[$OuterLoop][$InnerLoop]
}
}
# Results
<#
The value of [0][0] ---> Player001
The value of [0][1] ---> 200
The value of [1][0] ---> Player002
The value of [1][1] ---> 199
The value of [2][0] ---> Player003
The value of [2][1] ---> 300
#>
# Arrray count
$ScoreDetails.Count
# Results
<#
3
#>
# Array details
$ScoreDetails |
Select-Object -Property '*'
# Results
<#
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player001, 200}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player002, 199}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player003, 300}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
#>
# Modify an entry
$ScoreDetails[0][1] = 250
# Arrray count
$ScoreDetails.Count
# Results
<#
3
#>
# Array details
$ScoreDetails |
Select-Object -Property '*'
# Results
<#
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player001, 250}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player002, 199}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player003, 300}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
#>
Update as per your comment
using the cast [System.Collections.ArrayList] would not allow me to do what I wanted - still, it drew my attention to considering the "cast" of my array.
... as per my follow-up comment to you. For example:
$ScoreDetails = @()
$ScoreDetails = @(
@('Player001', '200'),
@('Player002', '199')
)
# ...
'Enter NEXT player score details'
$name = Read-Host 'Name'
$score = Read-host 'Score'
$ScoreDetails += ,(@($name,$score))
# ...
for(
$OuterLoop = 0
$OuterLoop -lt 3
$OuterLoop ++
)
{
for(
$InnerLoop = 0
$InnerLoop -lt 2
$InnerLoop ++
)
{
"The value of [$OuterLoop][$InnerLoop] ---> " +
$ScoreDetails[$OuterLoop][$InnerLoop]
}
}
#...
$ScoreDetails |
Select-Object -Property '*'
# Results
<#
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player001, 200}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player002, 199}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player003, 100}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
#>
$ScoreDetails[0][1] = 250
$ScoreDetails |
Select-Object -Property '*'
# Results
<#
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player001, 250}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player002, 199}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player003, 100}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
#>
$ScoreDetails[1][1] = '199, 300'
$ScoreDetails |
Select-Object -Property '*'
# Results
<#
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player001, 250}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player002, 199, 300}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 2
Length : 2
LongLength : 2
Rank : 1
SyncRoot : {Player003, 100}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
#>
Upvotes: 0
Reputation: 175084
Nested/jagged arrays are usually not the best choice of data structure in PowerShell (as you seem to have found out :) ), and I'd suggest using a hashtable (@{}
) instead:
$userEventIDs = @{
'user1' = @(23, 4523)
'user2' = @(5670, 2300)
'user3' = @(321, 1299)
}
Adding a new event ID for a specific user now becomes trivial (notice I'm using +=
, not =
):
PS ~> $userEventIDs['user1'] += @(4567, 1234)
PS ~> $userEventIDs['user1'].Count
4
Upvotes: 4