Arrays Powershell中避免不可知锯齿阵列平坦化

Arrays Powershell中避免不可知锯齿阵列平坦化,arrays,powershell,jagged-arrays,Arrays,Powershell,Jagged Arrays,我在Powershell中遇到了一个有趣的问题,但尚未找到解决方案。当我在谷歌上搜索(并找到类似的东西)时,没有什么比我想做的事情更复杂的了,所以我想我应该把问题贴在这里 这个问题与外部数组长度为1的多维数组有关。Powershell似乎非常坚决地要将数组展平,例如@(@('A'))变成@('A')。以下是第一个代码段(提示为>,顺便说一句): 因此,我希望$a[0].gettype().isarray为true,这样我就可以将值索引为$a[0][0](现实世界中的场景是在循环内部处理动态数组,

我在Powershell中遇到了一个有趣的问题,但尚未找到解决方案。当我在谷歌上搜索(并找到类似的东西)时,没有什么比我想做的事情更复杂的了,所以我想我应该把问题贴在这里

这个问题与外部数组长度为1的多维数组有关。Powershell似乎非常坚决地要将数组展平,例如
@(@('A'))
变成
@('A')
。以下是第一个代码段(提示为>,顺便说一句):

因此,我希望
$a[0].gettype().isarray
为true,这样我就可以将值索引为
$a[0][0]
(现实世界中的场景是在循环内部处理动态数组,我希望得到
$a[$I][$j]
,但如果内部项不是作为数组而是作为字符串识别的话(在我的情况下),开始索引到字符串的字符,如
$a[0][0]-eq'T'

我有两个很长的代码示例,所以我在最后发布了它们。作为参考,这是在安装了PSv2和PSCX的Windows7Ultimate上实现的

考虑代码示例1:我使用+=运算符手动构建一个简单数组。中间数组
$w
被展平,因此无法正确添加到最终数组中。我在网上找到了类似问题的解决方案,基本上是在内部数组之前加一个逗号,以迫使外部数组不展平,这确实有效,但我正在寻找一种可以在循环中构建数组的解决方案(数组的锯齿状数组,处理CSS文件),因此,如果我将前导逗号添加到单元素数组(实现为中间数组
$y
),我希望对其他数组(如
$z
)执行相同的操作,但这会对如何将
$z
添加到最终数组产生不利影响

现在考虑<强>代码示例2 < /强>:这更接近我所遇到的实际问题。当从函数返回包含一个元素的多维数组时,它将被展平。它在离开函数之前是正确的。同样,这些都是示例,我真的在尝试处理一个文件,而不必知道函数返回时是使用

@(@('color','black'))
还是使用
@(@('color','black'),@('background color','white'))

有人遇到过这个问题吗?有人解决了这个问题吗?我知道我可以实例化框架对象,我假设如果我创建一个对象[],或者一个列表,或者其他类似的东西,一切都会很好,但是我已经处理了一段时间了,似乎一定要有一个正确的方法来做这件事(不必实例化真正的框架对象)

代码示例1 代码示例2
谢谢,马特,还有一个问题是从同一个问题开始的:。看起来这是设计完成的

我认为如果您返回
,$ret
而不是
$ret
,它应该可以工作

还有两个注意事项:

  • 您可以测试该项是否为数组by
    $item-is[array]
    (只是因为它看起来更像PowerShell;)
  • @()
    仅对非数组的项有效。如果您链接
    @(@(@(1)))
    ,您将得到一个包含一个int项的数组(
    @(@(@(@(1)))[0]。gettype()
    返回Int32)。
    因此,
    @(,@('r','s'))
    ,@('r','s')
    相同

我尝试了stej所说的话,并使用以下示例:

function funC([int]$numOfPairs)
{
  $ret = @()
  if($numOfPairs -eq 1)
  { $ret = ,@('r','s') }
  elseif($numOfPairs -eq 2)
  { $ret = @('r','s'),@('t','u') }
  else
  { $ret = @('r','s'),@('t','u'),@('v','w') }

  Display $ret 0 "Inside Function C ($numOfPairs)"
  return ,$ret
}


### Start Program

$z = funC 1
Display $z 0 'Return from Function C(1)'
$z = funC 2
Display $z 0 'Return from Function C(2)'
$z = funC 3
Display $z 0 'Return from Function C(3)'

在您的第一个代码示例中,而不是
$a=@(@('Test'))
执行:
$a=@(,@('Test'))
,然后通过
$a[0][0]
进行尝试,并惊奇地发现PowerShell语法有多么可怕。添加single“,”不仅改变了此行为,而且元素仍然是[0][0]而不是[1][0],正如数组中逗号的数量所表明的那样。。事实证明,在这种情况下,逗号不是元素分隔符。
function Display($x, [int]$indent, [string]$title)
{
  if($title -ne '') { write-host "$title`: " -foregroundcolor cyan -nonewline }
  if(!$x.GetType().IsArray)
  { write-host "'$x'" -foregroundcolor cyan }
  else
  {
    write-host ''
    $s = new-object string(' ', $indent)
    for($i = 0; $i -lt $x.length; $i++)
    {
      write-host "$s[$i]: " -nonewline -foregroundcolor cyan
      Display $x[$i] $($indent+1)
    }
  }
  if($title -ne '') { write-host '' }
}


### Start Program
$final = @( @( 'a', 'b' ), @('c'))
Display $final 0 'Initial Value'

### How do we do this part ??? ###########
                                        ##
$w = @( @('d', 'e') )                   ##
$x = @( @('f', 'g'), @('h') )           ##
# But now $w is flat, $w.length = 2     ##
                                        ##
                                        ##
# Even if we put a leading comma (,)    ##
# in front of the array, $y will work   ##
# but $w will not. This can be a        ##
# problem inside a loop where you don't ##
# know the length of the array, and you ##
# need to put a comma in front of       ##
# single- and multidimensional arrays.  ##
$y = @( ,@('D', 'E') )                  ##
$z = @( ,@('F', 'G'), @('H') )          ##
                                        ##
                                        ##
##########################################

$final += $w
$final += $x
$final += $y
$final += $z
Display $final 0 'Final Value'


### Desired final value: @( @('a', 'b'), @('c'), @('d', 'e'), @('f', 'g'), @('h'), @('D', 'E'), @('F', 'G'), @('H') )
### As in the below:
# 
# Initial Value:
# [0]:
#  [0]: 'a'
#  [1]: 'b'
# [1]:
#  [0]: 'c'
# 
# Final Value:
# [0]:
#  [0]: 'a'
#  [1]: 'b'
# [1]:
#  [0]: 'c'
# [2]:
#  [0]: 'd'
#  [1]: 'e'
# [3]:
#  [0]: 'f'
#  [1]: 'g'
# [4]:
#  [0]: 'h'
# [5]:
#  [0]: 'D'
#  [1]: 'E'
# [6]:
#  [0]: 'F'
#  [1]: 'G'
# [7]:
#  [0]: 'H'
function Display($x, [int]$indent, [string]$title)
{
  if($title -ne '') { write-host "$title`: " -foregroundcolor cyan -nonewline }
  if(!$x.GetType().IsArray)
  { write-host "'$x'" -foregroundcolor cyan }
  else
  {
    write-host ''
    $s = new-object string(' ', $indent)
    for($i = 0; $i -lt $x.length; $i++)
    {
      write-host "$s[$i]: " -nonewline -foregroundcolor cyan
      Display $x[$i] $($indent+1)
    }
  }
  if($title -ne '') { write-host '' }
}



function funA()
{
  $ret = @()
  $temp = @(0)
  $temp[0] = @('p', 'q')
  $ret += $temp
  Display $ret 0 'Inside Function A'
  return $ret # What about return ,$ret ? What about if $ret = @( @('p', 'q'), @('r', 's') ) -- would return ,$ret still work?
}

function funB()
{
  $ret = @( ,@('r', 's') )
  Display $ret 0 'Inside Function B'
  return $ret
}


### Start Program

$z = funA
Display $z 0 'Return from Function A'
$z = funB
Display $z 0 'Return from Function B'


### Desired final value: @( @('p', 'q') )  and same for r,s
### As in the below:
# 
# Inside Function A:
# [0]:
#  [0]: 'p'
#  [1]: 'q'
# 
# Return from Function A:
# [0]:
#  [0]: 'p'
#  [1]: 'q'
function funC([int]$numOfPairs)
{
  $ret = @()
  if($numOfPairs -eq 1)
  { $ret = ,@('r','s') }
  elseif($numOfPairs -eq 2)
  { $ret = @('r','s'),@('t','u') }
  else
  { $ret = @('r','s'),@('t','u'),@('v','w') }

  Display $ret 0 "Inside Function C ($numOfPairs)"
  return ,$ret
}


### Start Program

$z = funC 1
Display $z 0 'Return from Function C(1)'
$z = funC 2
Display $z 0 'Return from Function C(2)'
$z = funC 3
Display $z 0 'Return from Function C(3)'