PowerShell에서 불가지론적인 들쭉날쭉 한 배열 평평한 것을 피합니다

StackOverflow https://stackoverflow.com/questions/2463190

문제

나는 PowerShell에서 흥미로운 문제를 겪고 있으며 그것에 대한 해결책을 찾을 수 없었습니다. 내가 구글을 할 때 (그리고 같은 것을 찾을 때 이 게시물), 내가하려고하는 것만 큼 관련된 것은 없기 때문에 여기에 질문을 게시 할 것이라고 생각했습니다.

문제는 외부 어레이 길이의 다차원 배열과 관련이 있습니다. PowerShell은 배열과 같은 평평한 배열에 대해 매우 단호한 것 같습니다. @( @('A') ) becomes @( 'A' ). 다음은 첫 번째 스 니펫입니다 (프롬프트는>, btw) :

> $a =  @( @( 'Test' ) )
> $a.gettype().isarray
True
> $a[0].gettype().isarray
False

그래서, 나는 가고 싶다 $a[0].gettype().isarray 내가 값을 $a[0][0] (실제 시나리오는 루프 내부의 동적 배열을 처리하는 것입니다. $a[$i][$j], 그러나 내부 항목이 배열로 인식되지 않고 문자열 (내 경우)으로 인식되면 문자열의 문자로 인덱싱을 시작합니다. $a[0][0] -eq 'T').

몇 가지 긴 코드 예제가 있으므로 마지막에 게시했습니다. 참고로, 이것은 PSV2 및 PSCX가 설치된 Windows 7 Ultimate에 있습니다.

고려하다 코드 예제 1: += 연산자를 사용하여 수동으로 간단한 배열을 빌드합니다. 중간 배열 $w 평평 해져서 결과적으로 최종 배열에 올바르게 추가되지 않습니다. 비슷한 문제에 대한 솔루션을 찾았습니다. 기본적으로 내부 배열 앞에 쉼표를 배치하여 외부 어레이가 평평하지 않도록 강제로 작동하지만 다시 루프 내부에 배열을 빌드 할 수있는 솔루션을 찾고 있습니다 (). CSS 파일을 처리하는 배열 배열, Jagged Array). 단일 요소 배열에 선행 쉼표를 추가하는 경우 (중간 배열로 구현 $y), 나는 다른 배열에 대해 똑같이하고 싶다 (: $z), 그러나 그것은 어떻게 부정적인 영향을 미칩니다 $z 최종 배열에 추가됩니다.

이제 고려하십시오 코드 예제 2: 이것은 내가 가진 실제 문제에 더 가깝습니다. 하나의 요소가있는 다차원 배열이 함수에서 반환되면 평평합니다. 기능을 떠나기 전에 맞습니다. 그리고 다시, 이것들은 그 예입니다. 저는 기능이 다시 올 것인지 알지 않고도 파일을 처리하려고합니다. @( @( 'color', 'black') ) 또는 함께 @( @( 'color', 'black'), @( 'background-color', 'white') )

누구든지 이것을 만나고 누군가를 해결 한 사람이 있습니까? 나는 프레임 워크 객체를 인스턴스화 할 수 있다는 것을 알고 있으며, 객체 [] 또는 목록 <> 또는 다른 비슷한 것을 만들면 모든 것이 괜찮을 것이라고 가정하지만, 이것을 조금씩 다루고 있습니다. 확실히이 작업을 수행하는 올바른 방법이 있어야하는 것 같습니다 (진정한 프레임 워크 객체를 인스턴스화하지 않아도).

코드 예제 1

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'

코드 예제 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'

고마워요, 매트

도움이 되었습니까?

해결책

같은 문제로 시작하는 또 다른 질문이 있습니다. PowerShell 함정 . 이것은 디자인으로 이루어진 것 같습니다.

당신이 돌아 오면 생각합니다 ,$ret 대신에 $ret, 작동해야합니다.

두 개의 메모 :

  • 항목이 배열 인 경우 테스트 할 수 있습니다. $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)'
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top