【问题标题】:Updating Multi-Dimensional Array not working - (looked at other similar questions - no help)更新多维数组不起作用 - (查看其他类似问题 - 没有帮助)
【发布时间】:2021-07-19 06:20:38
【问题描述】:

我正在尝试使用可以更新和添加新用户的 eventID 列表创建用户名数组,即 (('user1', '23,4523'), ('user2', '5670,2300') , ('user3','321,1299') )

当我使用第一个用户初始化数组并使用其他事件更新该用户时,我得到了预期的结果。

PS> $usrProfile
user1
4567,1234

当我添加一个新用户('user2','6688')而不是获得数组计数'2'时,它仍然是'1'并且数组返回数组对象详细信息.....好吧,所以我觉得可行

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

....然后当我更新'user2'时轮子脱落,原来的'user1'记录消失并且'user2'具有更新的值,但失去了初始值。此外,最初 foreach 循环中的 $item[0] 返回用户名,添加新用户后 $item[0] 返回对象信息..

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

这些是命令...

$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

我已经花了几天时间,但没有取得任何进展....提前感谢和感谢任何能发现我做错的人......这是代码......

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
}

【问题讨论】:

  • 这与您的问题无关,但有一点值得了解:if ( ($initFlag -eq $false ) -AND ($UpdUserFlag -eq $false) ) 可以替换为 if (-not $initFlag -AND -not $UpdUserFlag)if (!$initFlag -AND !$UpdUserFlag)

标签: arrays powershell multidimensional-array


【解决方案1】:

嵌套/锯齿状数组通常不是 PowerShell 中数据结构的最佳选择(您似乎已经发现 :)),我建议改用哈希表 (@{}):

$userEventIDs = @{
  'user1' = @(23, 4523)
  'user2' = @(5670, 2300) 
  'user3' = @(321, 1299)
}

现在为特定用户添加新事件 ID 变得很简单(注意我使用的是 +=,而不是 =):

PS ~> $userEventIDs['user1'] += @(4567, 1234)
PS ~> $userEventIDs['user1'].Count
4

【讨论】:

  • Mathias,这成功了!非常感谢!
  • @Digital,确保将其标记为答案,以便将来的读者可以遇到此解决方案:)
【解决方案2】:

如果我关注你,这就是你的用例所追求的吗?

# 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
#>

根据您的评论更新

使用演员表 [System.Collections.ArrayList] 不允许我这样做 我想要什么 - 尽管如此,它还是让我注意到考虑“演员” 我的数组。

...根据我对您的后续评论。例如:

$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
#>

【讨论】:

  • 谢谢你,使用演员表 [System.Collections.ArrayList] 不会让我做我想做的事 - 尽管如此,它还是让我注意考虑我的数组的“演员表”。
  • 不用担心,但您可以在没有明确的[System.Collections.ArrayList] 的情况下执行此操作。为了清楚起见,这是我养成的习惯。所以,这个$ScoreDetails = @() 也同样有效。
猜你喜欢
  • 2014-12-06
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 2013-09-23
  • 2018-03-14
相关资源
最近更新 更多