我可以直观地找出大多数语言,但显然不是Powershell。
我想创建一个数组数组(这将包含磁盘目录和计数,所以稍后我可以验证我们至少有那么多文件)。
从那个数组数组中,我想拉出一个只有目录名的数组,这样我就可以将它传递给Get-ChildItem。
$DirInfo = @('d:\Work',2),
('d:\Temp',3)
$DirNameArray=@() #declare empty array
foreach ($item in $DirInfo)
{
$DirNameArray += , $item[0] #tried with and without the comma here
Write-Host 'Loop1 ' $item[0]
}
write-host $DirNameArray.count
#Let's Verify what we got so we know how many items we have in our array
Write-Host "Verify with a loop"
foreach ($dir in $DirNameArray)
{
Write-Host 'Loop2:' $dir
}
Write-Host "Verify the other way"
Write-Host $DirNameArray
实际结果:
Loop1 d:\Work
Loop1 d:\Temp
1
Verify with a loop
Loop2: d:\Workd:\Temp
Verify the other way
d:\Workd:\Temp
我不明白为什么Loop2没有执行两次。 看起来= +只是将值串起来而不是向我的数组中添加一个名为$ DirNameArray的新项。
我仍然感到困惑,我创建的一个文件就是这样,并给了我预期的结果:
$a = "one","two"
Write-Host $a.count
$a += "three"
Write-Host $a.count
结果:
2
3
如果上述工作有效,为什么我的代码不起作用?
我创建的第二个文件是这样的 - 我不理解结果。我甚至将变量名称设置为不同,因此我不会处理该变量的任何先前定义或值:
$DirNameArray5="abc","def"
write-host $DirNameArray5.count
$DirNameArray5 += "xyz"
write-host $DirNameArray5.count
$DirNameArray5 += @("opq")
write-host $DirNameArray5.count
结果:
1
1
1
$DirNameArray7="abc","def"
write-host $DirNameArray7.count
$DirNameArray7 += "xyz"
write-host $DirNameArray7.count
$DirNameArray7 += @("opq")
write-host $DirNameArray7.count
结果:
2
3
4
显然,如果你曾经将变量定义为字符串,那么很难让Powershell将其重新定义为数组。
但我还有原来的问题。如何定义一个空数组,以便我可以使用+ =运算符在循环中添加它。
$DirNameArray=@()
我最后使用.GetType()方法来查看我的变量实际上是什么: PS C:\ Users \ nwalters> $ DirNameArray5.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
PS C:\Users\nwalters> $DirNameArray7.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
底线 - 这就是我想要的 - 尽可能少的代码行没有循环:
[string]$x=@() # declare empty array
Write-Host $x.GetType()
$x += "one"
$x += "two"
Write-Host $x.count
Write-Host $x
实际结果
System.String
1
onetwo
期望的结果:
object[] or string[]???
2
one two
答案 0 :(得分:2)
Powershell不允许您创建一个空数组,也不能让您将数组清空为零(一个例外)。我发现有两种方法可以解决此问题:
方法1:使用-OutVariable
来命名变量,以使用您的输入创建一个数组
Example: gci C:\TestDir1 -OutVariable test
使用.GetType()
方法返回:
$test.GetType()
Directory: C:\TestDir1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/20/2020 11:36 AM 8015 Test1.xls
-a---- 6/26/2020 12:59 PM 0 test2.txt
Module : CommonLanguageRuntimeLibrary
Assembly : mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
TypeHandle : System.RuntimeTypeHandle
DeclaringMethod :
BaseType : System.Object
UnderlyingSystemType : System.Collections.ArrayList
FullName : System.Collections.ArrayList
这将创建一个名为$ test的新变量,它是一个数组(因为其中包含多个项目)。 $test.gettype()
将对象显示为数组。
方法2:明确声明一个包含两个虚拟对象的数组,然后删除这两个虚拟对象。
[System.Collections.ArrayList]$array = "value1", "value2"
$array.remove("value1")
$array.remove("value2")
使用gettype方法仍将显示$test
是一个数组,即使它为空:
> $test.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True ArrayList System.Object
该数组现在将完全为空,可用于存储任何新输入。除非您像我在示例中那样明确命名变量类型,否则这是行不通的(不确定原因)。示例如下所示:
$test = "value1", "value2"
$test.Remove("value1")
Exception calling "Remove" with "1" argument(s): "Collection was of a fixed size."
At line:3 char:1
+ $test.Remove("value1")
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
P.S。我知道这是一个旧主题,但没有得到答案,我自己才遇到此问题,因此我为其他搜索此问题的人回答。
答案 1 :(得分:1)
以下代码在两台不同的计算机上进行测试,均使用PowerShell 2.0。你可以尝试这个并发布结果。
# declare an empty array $var = @() write-host "var.count = '$($var.count)' var.type ='$($var.GetType())' var.type.BaseType = '$($var.GetType().BaseType)'" # add a single item $var += "single item" write-host "var.count = '$($var.count)' var.type ='$($var.GetType())' var.type.BaseType = '$($var.GetType().BaseType)'" # add an array $var += , @("array 1 - item 1","array 1 - item 2") write-host "var.count = '$($var.count)' var.type ='$($var.GetType())' var.type.BaseType = '$($var.GetType().BaseType)'" # display the 'single item' write-host "single item = '$($var[0])'" # display first element of array item write-host "first element of array item = '$($var[1][0])'"
给了我
var.count = '0' var.type ='System.Object[]' var.type.BaseType = 'array' var.count = '1' var.type ='System.Object[]' var.type.BaseType = 'array' var.count = '2' var.type ='System.Object[]' var.type.BaseType = 'array' single item = 'single item' first element of array item = 'array 1 - item 1'