避免不可知论铁血阵列在PowerShell中压扁 [英] Avoiding Agnostic Jagged Array Flattening in Powershell
问题描述
我运行到PowerShell中一个有趣的问题,一直没能找到一个解决的办法。当我谷歌(和找东西像<一个href=\"http://stackoverflow.com/questions/1390782/jagged-powershell-array-is-losing-a-dimension-when-only-one-element-exists\">this帖子),什么能所涉及的什么,我试图做的来了,所以我想我会在这里发表的问题。
I'm running into an interesting problem in Powershell, and haven't been able to find a solution to it. When I google (and find things like this post), nothing quite as involved as what I'm trying to do comes up, so I thought I'd post the question here.
问题具有与一个的外数组长度多维数组做。看来PowerShell是关于扁平状阵列@(@('A'))
变成 @('A')$ C $态度十分坚决C>。这是第一个片段(提示是>,顺便说一句):
The problem has to do with multidimensional arrays with an outer array length of one. It appears Powershell is very adamant about flattening arrays like @( @('A') )
becomes @( 'A' )
. Here is the first snippet (prompt is >, btw):
> $a = @( @( 'Test' ) )
> $a.gettype().isarray
True
> $a[0].gettype().isarray
False
所以,我想有 $ a [0] .gettype()。IsArray的
是真实的,这样我可以索引值 $ A [0] [0]
(现实世界中的场景正在处理动态数组一个循环里面,我想获得的值 $ A [ $ i] [$ J]
,但如果<内物品不被识别为一个数组,但作为一个字符串(在我的情况),你开始索引到字符串中的字符,如code> $ a [0] [0] -eq'T')。
So, I'd like to have $a[0].gettype().isarray
be true, so that I can index the value as $a[0][0]
(the real world scenario is processing dynamic arrays inside of a loop, and I'd like to get the values as $a[$i][$j]
, but if the inner item is not recognized as an array but as a string (in my case), you start indexing into the characters of the string, as in $a[0][0] -eq 'T'
).
我有一对夫妇的长code的例子,所以我已经发布他们在最后。而且,以供参考,这是Windows 7旗舰版安装PSV2和PSCX。
I have a couple of long code examples, so I have posted them at the end. And, for reference, this is on Windows 7 Ultimate with PSv2 and PSCX installed.
考虑的 code例如1 :我建立一个简单的数组使用手动+ =操作符。中间阵列 $ W
变平,因此不会被添加到最终的阵列正常。我已经找到解决方案,在线为类似的问题,这主要涉及将一个逗号内阵列之前,迫使外阵列不是扁平化,这不工作,但同样,我在寻找能够建立一个循环内阵列的解决方案(阵列的交错数组,处理CSS文件),所以如果我添加的主要逗号单一元素的数组(作为中间阵列实施 $ Y
),我想做同样为其他阵列(如 $ Z而言
),但不利影响如何 $ Z而言
添加到最后一个数组。
Consider code example 1: I build a simple array manually using the += operator. Intermediate array $w
is flattened, and consequently is not added to the final array correctly. I have found solutions online for similar problems, which basically involve putting a comma before the inner array to force the outer array to not flatten, which does work, but again, I'm looking for a solution that can build arrays inside a loop (a jagged array of arrays, processing a CSS file), so if I add the leading comma to the single element array (implemented as intermediate array $y
), I'd like to do the same for other arrays (like $z
), but that adversely affects how $z
is added to the final array.
现在考虑的 code例如2 :这是更接近我有实际的问题。当一个元素的多维数组是由函数返回的,它被夷为平地。这是正确的离开函数之前。再次,这些都是例子,我真的想处理一个文件,而无需知道函数是否会回来与 @(@('色','黑'))
或 @(@('色','黑'),@('背景色','白'))
Now consider code example 2: This is closer to the actual problem I am having. When a multidimensional array with one element is returned from a function, it is flattened. It is correct before it leaves the function. And again, these are examples, I'm really trying to process a file without having to know if the function is going to come back with @( @( 'color', 'black') )
or with @( @( 'color', 'black'), @( 'background-color', 'white') )
有没有人遇到过这一点,已经有人解决了这个?我知道我可以实例化框架对象,我假设一切都会好起来,如果我创建了一个对象[],或列表&LT;>,还是别的什么类似的,但我一直在处理这个一点点东西确保好像必须有做到这一点(而无需真正的实例化框架对象)一个正确的方式。
Has anybody encountered this, and has anybody resolved this? I know I can instantiate framework objects, and I'm assuming everything will be fine if I create an object[], or a list<>, or something else similar, but I've been dealing with this for a little bit and something sure seems like there has to be a right way to do this (without having to instantiate true framework objects).
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'
code例2
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'
谢谢,马特
推荐答案
有是同样的问题开始了另一个问题:<一href=\"http://stackoverflow.com/questions/803521/powershell-pitfalls\">http://stackoverflow.com/questions/803521/powershell-pitfalls 。它看起来像这是由设计完成的。
There is another question that starts with the same problem: http://stackoverflow.com/questions/803521/powershell-pitfalls . It looks like this is done by design.
我想如果返回,$沤
而不是 $ RET
,它应该工作。
I think if you return ,$ret
instead of $ret
, it should work.
另外两个注意事项:
- 您可以测试,如果该项目是由数组
$项目-is [阵列]
(只是因为它看起来更像是PowerShell的;) -
@()
只对不属于数组项目的效果。如果您将@(@(@(1)))
,你会得到一个INT项(数组@(@(@(1 )))[0] .gettype()
返回的Int32)。
因此,@(@('R','S'))
相同,@('R','S')
。
- you can test, if the item is array by
$item -is [array]
(just because it looks more like PowerShell ;) @()
has effect only on items that are not arrays. If you chain@(@(@(1)))
, you will get an array with one int item (@(@(@(1)))[0].gettype()
returns Int32).
So,@( ,@('r', 's') )
is the same as,@('r', 's')
.
这篇关于避免不可知论铁血阵列在PowerShell中压扁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!