powershell 3d jagged tömb

Sziasztok!

A tárgyban szereplő dolgot szeretném megvalósítani, de nem megy. A 2d-s feltöltése így néz ki:


[System.Collections.ArrayList]$script:tdb=@()
$asd=@("nulla","egy","ketto","harom","negy","ot","hat","het","nyolc","kilenc","tiz")
$script:tdb+=,@()
for($x=0;$x -lt 10;$x++){
    $script:tdb+= ,@()
    $xdb="$x",$asd[$x]
    $script:tdb[$x]+=$xdb
    Write-Host $script:tdb[$x][0],";",$script:tdb[$x][1]
}

Ez működik, de van ezzel kapcsolatban is egy kérdésem. Miért nem működik ez:


    $script:tdb[$x]+=,@($x",$asd[$x])

A 3d-s feltöltésével így próbálkoztam, de nem jó:


[System.Collections.ArrayList]$script:tdb=@()
$asd=@("nulla","egy","ketto","harom","negy","ot","hat","het","nyolc","kilenc","tiz")
$script:tdb+=,@()
$y=0
for($x=0;$x -lt 4;$x++){
    $script:tdb[$y][$x]+=,@()
    $xdb="$x",$asd[$x]
    $script:tdb[$y][$x]+=$xdb
            [array]$ydb=$script:tdb[$y][$x]
            Write-Host $ydb[0], ";",$ydb[1]
    if(($x -eq 3) -and ($y -eq 0) ){
        $y++
        $x=0
    }
}

[formázás javítva]

Hozzászólások

Amit nagyon fontos megérteni a powershellel kapcsolatban, hogy a collectionöket nagyon nem úgy kezeli, ahogyan azt egy normális oop nyelvtől megszoktuk. A , és a @() két eltérő dolgot csinál, és attól függően mit szeretnél, kell alkalmaznod az egyiket, másikat vagy mindkettőt. Néhány példa amiből talán megérthető melyik mire jó:


$empty = @()
$oneElement1 = ,1
$oneElement2 = @(1)
$oneDimension = 1,2,3
$twoDimensions = (1,2,3),(4,5,6)

Tehát ha legalább 1 elemed van, az elemek közé ,-t írva tömböt kapsz. Ha 0 vagy nem ismert számú elemed van és mindenképp tömböt szeretnél, akkor használd a @()-t.

A másik fontos dolog, hogy a powershell bizonyos pontokon a collectionöket elemeire bontja és egyesével küldi le a pipelineon. Ez különösen akkor vicces, amikor a második dimenziót adod hozzá az első dimenziót alkotó tömbödhöz:


$t = @() # ezt a sort képzeld oda a többi példa elé
$t.Count # 0

$t += @() # semmi nem kerül hozzáadásra a tömbhöz, mintha ez a művelet ott se lenne
$t.Count # 0

$t += 1,2,3 # a három elem egyesével kerül hozzáadásra a tömbhöz
$t.Count # 3

$t += @(@()) # az üres tömb tömbként továbbra is csak egy üres tömb, vagyis semmi nem kerül hozzáadásra a tömbhöz
$t.Count # 0

$t += ,@() # ez egy két dimenziós tömb: [[]], ezt a powershell kibontja a belső tömbre: [], ami hozzáadódik a tömbhöz
$t.Count # 1

Még egy érdekesség a témában, néha hasznos:


$x = "abc","def","ghi"
$x.ToUpper() # ABC DEF GHI

A konkrét kérdésre pedig a következő postban válaszolok.

Ahogy ígértem, a konkrét válasz. Utólagos engedelmeddel kicsit alakítottam a scripteken, beleértve a formázást és a felesleges kódrészletek törlését. A 2D-s eset így néz ki az én verziómban:


[System.Collections.ArrayList] $script:tdb = @()

$asd = "nulla","egy","ketto","harom","negy","ot","hat","het","nyolc","kilenc","tiz"

for($x = 0; $x -lt 10; $x++) {
    $script:tdb += ,("$x",$asd[$x])

    Write-Host $script:tdb[$x][0],";",$script:tdb[$x][1]
}

A

$script:tdb[$x]+=,@($x",$asd[$x])

sor, ha önmagában áll a ciklusban, akkor azért nem működik, mert a tömb x. eleméhez akarsz új elemet hozzáadni, ami nem létezik. Ha előtte áll egy

$script:tdb += ,@()

sor is, akkor pedig azért nem lesz jó, mert 3 dimenziós tömböt fogsz kapni, aminek a második dimenziója mindig egy elemű.

A második esetben nem egészen értettem meg, mit is szeretnél kapni eredményül, ezért csak annyit tudok mondani, hogy a

$script:tdb[$y][$x]+=,@()

sor biztosan hibás, mert azon a ponton a második dimenziód még üres. Javaslom, hogy ehelyett akkor bővítsd a tömböt, amikor y olyan indexre mutat, ami még nem létezik, valahogy így:


if($y -ge $script:tdb.Count) {
    $script:tdb += ,@()
}

Felmerült bennem, hogy a te use case-edre nem tömbök tömbjét kellene használnod, hanem hashtable tömböt. Powershellben hashtable-t így lehet használni:


$h = @{Name1 = "Value1"; Name2 = "Value2"}
$h.Name1 # Value1

$h.Name2 = 123
$h.Name2 # 123

$h.Name3 = "Value3"
$h.Name3 # Value3

Köszönöm a válaszaidat, a formázást javítottam, rájöttem, hogy nem sima code tag kell, hanem bbcode-os.
Eléggé elvarázsolt még mindig számomra a powershell. Kitaláltam, hogy egy programozási feladatot ezzel fogok megoldani, hogy tanulgassam. Szerintem perlben már rég készen lennék vele. A fenti példáimat csak a gyakorláshoz, próbálgatáshoz készítettem. Az éles scriptben egy html fáljt szeretnék feldolgozni, ezért a három dimenzió. Én is gondolkodtam a hash használatában. A példánál még lehetne, de az éles feladatnál szerintem nem lenne jó. Az első dimenzió a html-ben lévő egymásba ágyazás miatt kellene. Tegnap már elkezdtem egy alternatív változaton dolgozni, ahol két tömböt használok, de azért még mindig jó lenne, ha megérteném, hogyan lehetne 3 dimenzióst használni.