Minden, amit tudni szeretne a tömbökről

A tömbök a legtöbb programozási nyelv alapvető nyelvi funkciója. Ezek olyan értékek vagy objektumok gyűjteményei, amelyeket nehéz elkerülni. Vessünk egy pillantást a tömbökre és az általuk kínált lehetőségekre.

Megjegyzés

A cikk eredeti verziója@KevinMarquette által írt blogon jelent meg. A PowerShell csapata köszönjük Kevinnek, hogy megosztotta velünk ezt a tartalmat. Kérjük, nézd meg a blog PowerShellExplained.com.

Mi a tömb?

Először egy alapvető technikai leírással kezdem, hogy mik azok a tömbök, és hogyan használják őket a legtöbb programozási nyelv, mielőtt továbblépnék a PowerShell más felhasználási módjaira.

A tömb olyan adatstruktúra, amely több elem gyűjteményeként szolgál. Az index használatával iterálhat a tömbben, vagy elérheti az egyes elemeket. A tömb szekvenciális memóriatömbként jön létre, ahol minden érték közvetlenül a másik mellett van tárolva.

Minden részletet érinteni fogok, ahogy megyünk.

Alapvető használat

Mivel a tömbök a PowerShell egyik alapvető funkciója, a PowerShellben való használatukhoz van egy egyszerű szintaxis.

Tömb létrehozása

Üres tömb a használatával hozható létre @()

PS> $data = @()
PS> $data.count
0

Létrehozhatunk egy tömböt, és csak zárójelekbe helyezzük őket @() értékekkel.

PS> $data = @('Zero','One','Two','Three')
PS> $data.count
4

PS> $data
Zero
One
Two
Three

Ez a tömb 4 elemet tartalmaz. Amikor meghívjuk a változót $data , megjelenik az elemek listája. Ha sztringek tömbje, akkor sztringenként egy sort kapunk.

Egy tömböt több sorban deklarálhatunk. A vessző ebben az esetben nem kötelező, és általában kimarad.

$data = @(
    'Zero'
    'One'
    'Two'
    'Three'
)

Inkább több sorban deklarálom a tömböket. A verziókövetés használata esetén nem csak a több elem esetén olvashatóbbá válik, hanem a korábbi verziókkal való összehasonlítás is.

Egyéb szintaxis

Általában ez @() a tömbök létrehozásának szintaxisa, de a vesszővel tagolt listák az idő nagy részében működnek.

$data = 'Zero','One','Two','Three'

Write-Output tömbök létrehozásához

Egy remek kis trükk, amelyet érdemes megemlíteni, hogy a Write-Output konzolon gyorsan létrehozhat sztringeket.

$data = Write-Output Zero One Two Three

Ez azért hasznos, mert nem kell idézőjeleket elhelyeznie a sztringek körül, amikor a paraméter elfogadja a sztringeket. Én soha nem tennék ezt a forgatókönyvet, de ez tisztességes játék a konzolon.

Elemek elérése

Most, hogy már van benne elemeket tartalmazó tömb, érdemes lehet ezeket az elemeket elérni és frissíteni.

Eltolás

Az egyes elemek eléréséhez a szögletes zárójeleket [] 0-tól kezdődő eltolási értékkel használjuk. Így kapjuk meg a tömb első elemét:

PS> $data = 'Zero','One','Two','Three'
PS> $data[0]
Zero

Azért használjuk itt a nullát, mert az első elem a lista elején van, ezért 0 elem eltolásával jutunk hozzá. A második elem eléréséhez az 1 eltolást kell használnunk az első elem kihagyásához.

PS> $data[1]
One

Ez azt jelentené, hogy az utolsó elem a 3. eltolásnál van.

PS> $data[3]
Three

Index

Most már láthatja, miért választottam ki azokat az értékeket, amelyeket ebben a példában tettem. Én vezettem be ezt, mint egy eltolás, mert ez az, amit valójában, de ez eltolás gyakrabban nevezik index. Egy index, amely a következővel 0kezdődik: . A cikk további részében indexnek nevezem az eltolást.

Speciális indexelési trükkök

A legtöbb nyelven csak egyetlen számot adhat meg indexként, és egyetlen elemet kaphat vissza. A PowerShell sokkal rugalmasabb. Egyszerre több indexet is használhat. Az indexek listájának megadásával több elemet is kiválaszthatunk.

PS> $data[0,2,3]
Zero
Two
Three

Az elemek a megadott indexek sorrendje alapján lesznek visszaadva. Ha duplikál egy indexet, az elemet mindkét alkalommal megkapja.

PS> $data[3,0,3]
Three
Zero
Three

A beépített .. operátorral megadhatja a számok sorozatát.

PS> $data[1..3]
One
Two
Three

Ez fordítva is működik.

PS> $data[3..1]
Three
Two
One

Negatív indexértékek használatával eltolhatja a végpontot. Ha tehát a lista utolsó elemére van szüksége, használhatja -1a következőt: .

PS> $data[-1]
Three

Egy szóval óvatosnak kell lenni az .. operátorral. A sorrend 0..-1 és -1..0 a kiértékelés az értékek 0,-1 és -1,0a . Könnyen látható $data[0..-1] , és úgy gondolja, hogy minden elemet enumerálna, ha elfelejtené ezt a részletet. $data[0..-1] ugyanazt az értéket adja meg, mint $data[0,-1] a tömb első és utolsó elemének megadásával (és a többi érték egyikével sem). Íme egy nagyobb példa:

PS> $a = 1,2,3,4,5,6,7,8
PS> $a[2..-1]
3
2
1
8

Ez ugyanaz, mint:

PS> $a[2,1,0,-1]
3
2
1
8

Kívülről

A legtöbb nyelvben, ha egy olyan elem indexét próbálja elérni, amely túl van a tömb végén, valamilyen hiba vagy kivétel jelenik meg. A PowerShell csendesen semmit sem ad vissza.

PS> $null -eq $data[9000]
True

Null értékű tömbbe nem indexelhető

Ha a változója, $null és tömbként próbálja indexelni, kivételt System.Management.Automation.RuntimeException kap az üzenettel Cannot index into a null array.

PS> $empty = $null
PS> $empty[0]
Error: Cannot index into a null array.

Ezért győződjön meg arról, hogy a tömbök nem $null azok, mielőtt megpróbál hozzáférni a bennük lévő elemekhez.

Darabszám

A tömbök és más gyűjtemények számláló tulajdonsága jelzi, hogy hány elem található a tömbben.

PS> $data.count
4

A PowerShell 3.0 a legtöbb objektumhoz hozzáadta a count tulajdonságot. lehet egyetlen objektum, és meg kell adnia a számot 1.

PS> $date = Get-Date
PS> $date.count
1

Még számláló tulajdonsága is $null van, kivéve a visszaadott értéket 0.

PS> $null.count
0

Van néhány trap itt, hogy én majd újra, amikor lefedi ellenőrzése $null , vagy üres tömbök később ebben a cikkben.

Egyszeri hibák

Gyakori programozási hiba jön létre, mert a tömbök a 0. indexnél kezdődnek. Az egyszeri hibák kétféleképpen vezethetők be.

Az első a szellemi gondolkodás azt szeretné, hogy a második elem, és használja az indexet 2 , és valóban szerzés a harmadik tétel. Vagy ha úgy gondolja, hogy négy eleme van, és az utolsót szeretné, akkor a darabszám használatával érheti el az utolsó elemet.

$data[ $data.count ]

A PowerShell tökéletesen örül, hogy ezt lehetővé teszi, és pontosan megadja, hogy pontosan milyen elem található a 4. indexben: $null. Önnek kell használnia $data.count - 1 , vagy a -1 fentebb megismertet.

PS> $data[ $data.count - 1 ]
Three

Itt szerezheti be az utolsó elemet az -1 index használatával.

PS> $data[ -1 ]
Three

Lee Dailey arra is rámutatott, hogy a maximális indexszám lekéréséhez használhatjuk $data.GetUpperBound(0) .

PS> $data.GetUpperBound(0)
3
PS> $data[ $data.GetUpperBound(0) ]
Three

A második leggyakoribb módszer a lista iterálása, és nem a megfelelő időben történő leállítás. Ezt újra megnézem, amikor a for hurok használatáról beszélünk.

Elemek frissítése

Ugyanezzel az indexszel frissíthetjük a tömb meglévő elemeit. Ez közvetlen hozzáférést biztosít az egyes elemek frissítéséhez.

$data[2] = 'dos'
$data[3] = 'tres'

Ha az utolsó elemen túli elemet próbálunk frissíteni, hibaüzenet jelenik Index was outside the bounds of the array. meg.

PS> $data[4] = 'four'
Index was outside the bounds of the array.
At line:1 char:1
+ $data[4] = 'four'
+ ~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
+ FullyQualifiedErrorId : System.IndexOutOfRangeException

Ezt később újra megismétlem, amikor arról beszélek, hogyan lehet nagyobb tömböt létrehozni.

Iteráció

Előfordulhat, hogy végig kell járnia vagy iterálnia kell a teljes listát, és végre kell hajtania néhány műveletet a tömb minden eleméhez.

Folyamat

A tömbök és a PowerShell-folyamat egymásnak szól. Ez az értékek feldolgozásának egyik legegyszerűbb módja. Amikor átad egy tömböt egy folyamatnak, a tömb minden eleme külön-külön lesz feldolgozva.

PS> $data = 'Zero','One','Two','Three'
PS> $data | ForEach-Object {"Item: [$PSItem]"}
Item: [Zero]
Item: [One]
Item: [Two]
Item: [Three]

Ha még nem látta $PSItem , csak tudd, hogy ez ugyanaz, mint $_. Bármelyiket használhatja, mert mindkettő a folyamat aktuális objektumát képviseli.

ForEach hurok

A ForEach hurok jól működik a gyűjteményekkel. A szintaxis használata: foreach ( <variable> in <collection> )

foreach ( $node in $data )
{
    "Item: [$node]"
}

ForEach metódus

Általában elfelejtem ezt, de jól működik az egyszerű műveletekhez. A PowerShell lehetővé teszi egy gyűjtemény meghívását .ForEach() .

PS> $data.foreach({"Item [$PSItem]"})
Item [Zero]
Item [One]
Item [Two]
Item [Three]

A .foreach() parancsprogram egy szkriptblokknak számító paramétert vesz fel. Elvetheti a zárójeleket, és csak megadhatja a szkriptblokkot.

$data.foreach{"Item [$PSItem]"}

Ez egy kevésbé ismert szintaxis, de ugyanúgy működik. Ezt a foreach metódust a PowerShell 4.0-ban adták hozzá.

A for hurok

A for hurkot a legtöbb más nyelven erősen használják, de a PowerShellben nem sok. Ha ezt látja, az gyakran egy tömb sétáltatásának kontextusában történik.

for ( $index = 0; $index -lt $data.count; $index++)
{
    "Item: [{0}]" -f $data[$index]
}

Az első dolog, amit teszünk, hogy inicializáljuk $index a következőt 0: . Ezután hozzáadjuk azt a feltételt, amelynél $index kisebbnek $data.countkell lennie. Végül megadjuk, hogy minden alkalommal, amikor hurkot, hogy nekem kell növelni az indexet.1 Ebben az esetben $index++ a rövid .$index = $index + 1 A formátumoperátor (-f) a kimeneti sztring értékének $data[$index] beszúrására szolgál.

Minden alkalommal, amikor hurkot for használ, különös figyelmet kell fordítania a feltételre. Én is itt használtam $index -lt $data.count . A logikában könnyen lekérhető, hogy a feltétel kissé helytelen. Használ, $index -le $data.count vagy $index -lt ($data.count - 1) mindig olyan kissé rossz. Ez azt eredményezné, hogy az eredmény túl sok vagy túl kevés elemet dolgoz fel. Ez a klasszikus off-by-one hiba.

Kapcsolóhurok

Ez egy olyan, amely könnyen figyelmen kívül hagyható. Ha megad egy tömböt egy kapcsolóutasításhoz, az ellenőrzi a tömb minden elemét.

$data = 'Zero','One','Two','Three'
switch( $data )
{
    'One'
    {
        'Tock'
    }
    'Three'
    {
        'Tock'
    }
    Default
    {
        'Tick'
    }
}
Tick
Tock
Tick
Tock

A switch utasítással sok jó dolgot tehetünk. Van egy másik cikket szentelt erre.

Értékek frissítése

Ha a tömb sztringek vagy egész számok (értéktípusok) gyűjteménye, előfordulhat, hogy érdemes frissíteni a tömb értékeit, miközben hurkot hoz létre rajtuk. A fenti hurkok többsége egy változót használ a hurokban, amely az érték másolatát tartalmazza. Ha frissíti ezt a változót, a tömb eredeti értéke nem frissül.

Az utasítás alól kivételt képez a for hurok. Ha végig szeretne járni egy tömböt, és frissíteni szeretné benne az értékeket, akkor a for hurok az, amit keres.

for ( $index = 0; $index -lt $data.count; $index++ )
{
    $data[$index] = "Item: [{0}]" -f $data[$index]
}

Ez a példa egy index szerinti értéket vesz fel, módosít néhány módosítást, majd ugyanazt az indexet használja a visszaadáshoz.

Objektumok tömbjei

Eddig csak egy értéktípust helyeztünk el egy tömbben, de a tömbök is tartalmazhatnak objektumokat.

$data = @(
    [pscustomobject]@{FirstName='Kevin';LastName='Marquette'}
    [pscustomobject]@{FirstName='John'; LastName='Doe'}
)

Sok parancsmag objektumgyűjteményeket ad vissza tömbökként, amikor egy változóhoz rendeli őket.

$processList = Get-Process

A már említett alapvető funkciók továbbra is érvényesek az objektumtömbökre, és néhány részletre érdemes rámutatni.

Tulajdonságok elérése

Az indexekkel ugyanúgy érhetünk el egy gyűjtemény egyes elemeit, mint az értéktípusok esetében.

PS> $data[0]

FirstName LastName
-----     ----
Kevin     Marquette

A tulajdonságokat közvetlenül is elérhetjük és frissíthetjük.

PS> $data[0].FirstName

Kevin

PS> $data[0].FirstName = 'Jay'
PS> $data[0]

FirstName LastName
-----     ----
Jay       Marquette

Tömbtulajdonságok

Az összes tulajdonság eléréséhez általában a teljes listát a következőképpen kell számbavétele:

PS> $data | ForEach-Object {$_.LastName}

Marquette
Doe

Vagy a Select-Object -ExpandProperty parancsmag használatával.

PS> $data | Select-Object -ExpandProperty LastName

Marquette
Doe

A PowerShell azonban lehetővé teszi számunkra a közvetlen kérést LastName . A PowerShell mindet számba adja számunkra, és egy tiszta listát ad vissza.

PS> $data.LastName

Marquette
Doe

Az enumerálás továbbra is megtörténik, de a mögöttes összetettség nem látható.

Where-Object szűrés

Ez az a hely, ahol Where-Object az objektum tulajdonságai alapján szűrhetjük és kiválaszthatjuk, hogy mit szeretnénk kivenni a tömbből.

PS> $data | Where-Object {$_.FirstName -eq 'Kevin'}

FirstName LastName
-----     ----
Kevin     Marquette

Ugyanezt a lekérdezést megírhatjuk a FirstName keresett lekérdezés lekéréséhez.

$data | Where FirstName -eq Kevin

Hol()

A tömbök olyan metódussal rendelkeznek Where() , amely lehetővé teszi a szűrő megadását scriptblock .

$data.Where({$_.FirstName -eq 'Kevin'})

Ez a funkció a PowerShell 4.0-s verzióban lett hozzáadva.

Objektumok frissítése hurkokban

Értéktípusok esetén a tömb frissítésének egyetlen módja egy for loop használata, mivel az érték cseréjéhez ismerni kell az indexet. Az objektumokkal több lehetőség áll rendelkezésre, mivel referenciatípusok. Íme egy gyors példa:

foreach($person in $data)
{
    $person.FirstName = 'Kevin'
}

Ez a hurok a tömb minden objektumán végighalad $data . Mivel az objektumok hivatkozástípusok, a $person változó pontosan ugyanarra az objektumra hivatkozik, amely a tömbben található. Ezért a tulajdonságainak frissítései frissítik az eredetit.

Így sem tudja lecserélni az egész objektumot. Ha új objektumot próbál hozzárendelni a $person változóhoz, a változóhivatkozást olyanra frissíti, amely már nem a tömb eredeti objektumára mutat. Ez nem a várt módon működik:

foreach($person in $data)
{
    $person = [pscustomobject]@{
        FirstName='Kevin'
        LastName='Marquette'
    }
}

Operátorok

A PowerShell operátorai tömbökön is működnek. Némelyikük kissé másképp működik.

-join

Az -join operátor a legnyilvánvalóbb, ezért először nézzük meg. Szeretem az operátort -join , és gyakran használom. Összekapcsolja a tömb összes elemét a megadott karakterrel vagy sztringgel.

PS> $data = @(1,2,3,4)
PS> $data -join '-'
1-2-3-4
PS> $data -join ','
1,2,3,4

Az operátor egyik jellemzője, hogy -join egyetlen elemet kezel.

PS> 1 -join '-'
1

Ezt a naplózásban és részletes üzenetekben használom.

PS> $data = @(1,2,3,4)
PS> "Data is $($data -join ',')."
Data is 1,2,3,4.

-join $array

Itt van egy okos trükk, amit Lee Dailey mutatott nekem. Ha valaha is szeretne csatlakozni mindent elválasztó nélkül, ahelyett, hogy ezt:

PS> $data = @(1,2,3,4)
PS> $data -join $null
1234

A tömböt előtag nélkül is használhatja -join paraméterként. Nézze meg ezt a példát, és nézze meg, hogy miről beszélek.

PS> $data = @(1,2,3,4)
PS> -join $data
1234

-replace és -split

A többi operátor kedveli -replace és -split végrehajtja a tömb egyes elemeit. Nem mondhatom, hogy valaha is használta őket így, de itt van egy példa.

PS> $data = @('ATX-SQL-01','ATX-SQL-02','ATX-SQL-03')
PS> $data -replace 'ATX','LAX'
LAX-SQL-01
LAX-SQL-02
LAX-SQL-03

-contains

Az -contains operátor lehetővé teszi az értékek tömbjének ellenőrzését, hogy az tartalmaz-e egy megadott értéket.

PS> $data = @('red','green','blue')
PS> $data -contains 'green'
True

-in

Ha egyetlen értéket szeretne ellenőrizni, amely megfelel a több érték egyikének, használhatja az operátort -in . Az érték a bal oldalon, a tömb pedig az operátor jobb oldalán található.

PS> $data = @('red','green','blue')
PS> 'green' -in $data
True

Ez költséges lehet, ha a lista nagy. Gyakran használok regex mintát, ha több értéket ellenőrizek.

PS> $data = @('red','green','blue')
PS> $pattern = "^({0})$" -f ($data -join '|')
PS> $pattern
^(red|green|blue)$

PS> 'green' -match $pattern
True

-eq és -ne

Az egyenlőség és a tömbök összetettek lehetnek. Ha a tömb a bal oldalon van, a rendszer minden elemet összehasonlít. A visszatérés Truehelyett az egyező objektumot adja vissza.

PS> $data = @('red','green','blue')
PS> $data -eq 'green'
green

Az operátor használatakor -ne az összes olyan értéket megkapjuk, amely nem egyenlő az értékünkkel.

PS> $data = @('red','green','blue')
PS> $data -ne 'green'
red
blue

Ha ezt egy if() utasításban használja, a visszaadott érték egy True érték. Ha nem ad vissza értéket, akkor ez egy False érték. Mindkét következő utasítás kiértékelése a következő lesz True.

$data = @('red','green','blue')
if ( $data -eq 'green' )
{
    'Green was found'
}
if ( $data -ne 'green' )
{
    'And green was not found'
}

Ezt egy pillanat múlva megismétlem, amikor a tesztelésről $nullbeszélünk.

-egyezés

Az -match operátor megpróbálja egyezni a gyűjtemény minden elemével.

PS> $servers = @(
    'LAX-SQL-01'
    'LAX-API-01'
    'ATX-SQL-01'
    'ATX-API-01'
)
PS> $servers -match 'SQL'
LAX-SQL-01
ATX-SQL-01

Ha egyetlen értékkel használja -match , a speciális változók $Matches egyező adatokkal lesznek feltöltve. Nem ez a helyzet, ha a tömböt így dolgozzák fel.

Ugyanezt a megközelítést alkalmazhatjuk a következővel Select-String: .

$servers | Select-String SQL

Én egy közelebbi Select-Stringpillantást ,-match és a $matches változó egy másik post hívott A sok módja annak, hogy regex.

$null vagy üres

A tömbök tesztelése $null bonyolult lehet. Íme a tömbök gyakori csapdái.

Egy pillantással úgy tűnik, hogy ennek az utasításnak működnie kell.

if ( $array -eq $null)
{
    'Array is $null'
}

De átnéztem, hogyan -eq ellenőrzik a tömb egyes elemeit. Így több, egyetlen $null értékkel rendelkező elemet tartalmazó tömböt is használhatunk, amelyek kiértékelése $true

$array = @('one',$null,'three')
if ( $array -eq $null)
{
    'I think Array is $null, but I would be wrong'
}

Ezért ajánlott az operátor bal oldalára helyezni $null . Ez a forgatókönyv nem jelent problémát.

if ( $null -eq $array )
{
    'Array actually is $null'
}

A $null tömb nem ugyanaz, mint az üres tömb. Ha tudja, hogy rendelkezik tömbbel, ellenőrizze a benne lévő objektumok számát. Ha a tömb az $null, akkor a szám .0

if ( $array.count -gt 0 )
{
    "Array isn't empty"
}

Van még egy csapda, hogy vigyázzon erre. Akkor is használhatja a count függvényt, ha egyetlen objektummal rendelkezik, kivéve, ha az objektum egy PSCustomObject. Ezt a hibát a PowerShell 6.1-ben javítottuk. Ez jó hír, de sokan még mindig az 5.1-en vannak, és figyelni kell rá.

PS> $object = [PSCustomObject]@{Name='TestObject'}
PS> $object.count
$null

Ha továbbra is a PowerShell 5.1-ben dolgozik, az objektumot egy tömbbe burkolhatja, mielőtt ellenőrizené a darabszámot a pontos szám lekéréséhez.

if ( @($array).count -gt 0 )
{
    "Array isn't empty"
}

A biztonságos lejátszáshoz ellenőrizze, hogy van-e $null, majd ellenőrizze a darabszámot.

if ( $null -ne $array -and @($array).count -gt 0 )
{
    "Array isn't empty"
}

Minden -eq

Nemrég láttam, hogy valaki megkérdezi , hogyan ellenőrizheti, hogy egy tömb minden értéke egyezik-e egy adott értékkel. Reddit felhasználó /u/bis volt ez az okos megoldás , amely ellenőrzi a helytelen értékeket, majd tükrözi az eredményt.

$results = Test-Something
if ( -not ( $results -ne 'Passed') )
{
    'All results a Passed'
}

Hozzáadás tömbökhöz

Ezen a ponton kezd el azon tűnődni, hogyan adhat hozzá elemeket egy tömbhöz. A gyors válasz az, hogy nem lehet. A tömbök rögzített méretűek a memóriában. Ha növelnie kell, vagy egyetlen elemet kell hozzáadnia hozzá, akkor létre kell hoznia egy új tömböt, és át kell másolnia az összes értéket a régi tömbből. Ez sok munkának hangzik, azonban a PowerShell elrejti az új tömb létrehozásának összetettségét. A PowerShell a tömbök összeadási operátorát (+) implementálja.

Megjegyzés

A PowerShell nem valósít meg kivonási műveletet. Ha rugalmas alternatívát szeretne használni egy tömbhöz, általános objektumot kell használniaList.

Tömb hozzáadása

Az összeadás operátort tömbökkel használva új tömböt hozhatunk létre. Tehát ezt a két tömböt tekintve:

$first = @(
    'Zero'
    'One'
)
$second = @(
    'Two'
    'Three'
)

Összeadhatjuk őket, hogy új tömböt kapjunk.

PS> $first + $second

Zero
One
Two
Three

Plusz egyenlő +=

Létrehozhatunk egy új tömböt, és az alábbi módon adhatunk hozzá egy elemet:

$data = @(
    'Zero'
    'One'
    'Two'
    'Three'
)
$data += 'four'

Ne feledje, hogy minden alkalommal, amikor azt használja += , hogy duplikálja és létrehoz egy új tömböt. Ez nem jelent problémát a kis adathalmazok esetében, de rendkívül rosszul skálázható.

Folyamat-hozzárendelés

Bármely folyamat eredményeit hozzárendelheti egy változóhoz. Tömb, ha több elemet tartalmaz.

$array = 1..5 | ForEach-Object {
    "ATX-SQL-$PSItem"
}

Általában a folyamat használatakor a tipikus Egysoros PowerShell-vonalakra gondolunk. A folyamatot utasításokkal és más hurkokkal foreach() is kihasználhatjuk. Így ahelyett, hogy elemeket adnánk hozzá egy tömbhöz egy hurokban, elemeket helyezhetünk a folyamatba.

$array = foreach ( $node in (1..5))
{
    "ATX-SQL-$node"
}

Tömbtípusok

A PowerShellben alapértelmezés szerint egy tömb jön létre típusként [PSObject[]] . Ez lehetővé teszi, hogy bármilyen típusú objektumot vagy értéket tartalmazzon. Ez azért működik, mert minden a típustól PSObject öröklődik.

Erősen gépelt tömbök

Hasonló szintaxissal bármilyen típusú tömböt létrehozhat. Erősen beírt tömb létrehozásakor csak a megadott típusú értékeket vagy objektumokat tartalmazhat.

PS> [int[]] $numbers = 1,2,3
PS> [int[]] $numbers2 = 'one','two','three'
ERROR: Cannot convert value "one" to type "System.Int32". Input string was not in a correct format."

PS> [string[]] $strings = 'one','two','three'

Tömblista

Az elemek tömbhöz való hozzáadása az egyik legnagyobb korlátozás, de van néhány további gyűjtemény is, amelyekhez fordulhatunk, hogy megoldjuk ezt a problémát.

Ez ArrayList általában az egyik első dolog, amire gondolunk, amikor olyan tömbre van szükségünk, amellyel gyorsabban dolgozhatunk. Úgy viselkedik, mint egy objektumtömb minden olyan helyen, ahol szükségünk van rá, de gyorsan kezeli az elemek hozzáadását.

Az alábbiakban bemutatjuk, hogyan hozhatunk létre és ArrayList adhatunk hozzá elemeket.

$myarray = [System.Collections.ArrayList]::new()
[void]$myArray.Add('Value')

Ehhez a típushoz a .NET-be hívunk. Ebben az esetben az alapértelmezett konstruktort használjuk a létrehozásához. Ezután meghívjuk a Add metódust egy elem hozzáadásához.

Azért használom [void] a sor elején, hogy elnyomom a visszatérési kódot. Egyes .NET-hívások ezt teszik, és váratlan kimenetet hozhatnak létre.

Ha a tömbben csak sztringek találhatóak, akkor tekintse meg a StringBuilder használatát is. Ez majdnem ugyanaz, de van néhány módszer, amely csak a sztringek kezelésére használható. A StringBuilder kifejezetten teljesítményre tervezett.

Gyakran előfordul, hogy az emberek tömbökből lépnek ArrayList át. De olyan időpontból származik, amikor a C# nem rendelkezik általános támogatással. Az ArrayList általános támogatás elavult List[]

Általános lista

Az általános típus egy speciális C#-típus, amely egy általánosított osztályt határoz meg, a felhasználó pedig a létrehozáskor használt adattípusokat határozza meg. Ha tehát számokat vagy sztringeket szeretne listázni, meg kell határoznia int , hogy szeretne-e listát vagy string típusokat.

A sztringek listájának létrehozása az alábbiak szerint történik.

$mylist = [System.Collections.Generic.List[string]]::new()

Vagy egy számlistát.

$mylist = [System.Collections.Generic.List[int]]::new()

Egy meglévő tömböt az alábbihoz hasonló listára helyezhetünk anélkül, hogy először létrehoznánk az objektumot:

$mylist = [System.Collections.Generic.List[int]]@(1,2,3)

A szintaxist a PowerShell 5-ös és újabb verziójú utasításával using namespace rövidíthetjük le. Az using utasításnak a szkript első sorának kell lennie. A névtér deklarálásával a PowerShell lehetővé teszi, hogy a hivatkozáskor hagyja ki az adattípusokból.

using namespace System.Collections.Generic
$myList = [List[int]]@(1,2,3)

Ez sokkal használhatóbbá teszi.List

Ön is rendelkezik egy hasonló Add módszerrel. A Tömblista függvénytől eltérően nincs visszatérési érték a Add metódusban, így nem kell hozzá tartoznunk void .

$myList.Add(10)

És továbbra is hozzáférhetünk az elemekhez, mint más tömbök.

PS> $myList[-1]
10

List[PSObject]

Bármilyen típusú listát létrehozhat, de ha nem ismeri az objektumok típusát, [List[PSObject]] akkor azokat is felhasználhatja.

$list = [List[PSObject]]::new()

Remove()

Az ArrayList általános és az általános List[] egyaránt támogatja az elemek eltávolítását a gyűjteményből.

using namespace System.Collections.Generic
$myList = [List[string]]@('Zero','One','Two','Three')
[void]$myList.Remove("Two")
Zero
One
Three

Az értéktípusok használatakor eltávolítja az elsőt a listából. Az érték eltávolításához újra és újra meghívhatja. Ha rendelkezik hivatkozástípusokkal, meg kell adnia az eltávolítani kívánt objektumot.

[list[System.Management.Automation.PSDriveInfo]]$drives = Get-PSDrive
$drives.remove($drives[2])
$delete = $drives[2]
$drives.remove($delete)

Az eltávolítási true módszer akkor ad vissza, ha sikerült megtalálni és eltávolítani az elemet a gyűjteményből.

További gyűjtemények

Számos más gyűjtemény is használható, de ezek a jó általános tömbcserék. Ha többet szeretne megtudni ezekről a lehetőségekről, vessen egy pillantást erre a Gistre , amelyet Mark Kraus állított össze.

Egyéb árnyalatok

Most, hogy lefedtem az összes főbb funkciót, íme néhány további dolog, amit meg akartam említeni, mielőtt ezt becsomagolom.

Előre méretezett tömbök

Már említettem, hogy a tömbök méretét a létrehozásuk után nem módosíthatja. Előre meghatározott méretű tömböt úgy hozhatunk létre, hogy meghívjuk a new($size) konstruktorral.

$data = [Object[]]::new(4)
$data.count
4

Tömbök szorzása

Egy érdekes kis trükk az, hogy egy tömböt meg lehet szorozni egész számmá.

PS> $data = @('red','green','blue')
PS> $data * 3
red
green
blue
red
green
blue
red
green
blue

Inicializálás a 0-val

Gyakori forgatókönyv, hogy minden nullával rendelkező tömböt szeretne létrehozni. Ha csak egész számokat szeretne megadni, akkor az egész számok erősen beírt tömbje alapértelmezés szerint minden nullát tartalmaz.

PS> [int[]]::new(4)
0
0
0
0

Erre is használhatjuk a szorzó trükköt.

PS> $data = @(0) * 4
PS> $data
0
0
0
0

A szorzási trükkben az a jó, hogy bármilyen értéket használhat. Tehát, ha inkább az 255 alapértelmezett értéket, ez egy jó módja annak, hogy ezt.

PS> $data = @(255) * 4
PS> $data
255
255
255
255

Beágyazott tömbök

A tömbökben lévő tömböket beágyazott tömbnek nevezzük. Ezeket nem használom sokat a PowerShellben, de más nyelveken is használtam őket. Fontolja meg tömbök tömbjének használatát, ha az adatok elférnek egy rácsban, mint egy minta.

Kétféleképpen hozhatunk létre kétdimenziós tömböt.

$data = @(@(1,2,3),@(4,5,6),@(7,8,9))

$data2 = @(
    @(1,2,3),
    @(4,5,6),
    @(7,8,9)
)

A vessző nagyon fontos ezekben a példákban. Egy korábbi példát adtam egy normál tömbre több sorban, ahol a vessző megadása nem kötelező. Ez nem így van a többdimenziós tömbök esetében.

Az index jelölésének használata kissé változik most, hogy beágyazott tömböt használunk. $data A fentieket használva így férhetünk hozzá a 3 értékhez.

PS> $outside = 0
PS> $inside = 2
PS> $data[$outside][$inside]
3

Adjon hozzá egy szögletes zárójelet a tömbök beágyazásának minden szintjéhez. Az első szögletes zárójel a külső legtöbb tömbhöz tartozik, majd onnan befelé halad.

Write-Output -NoEnumerate

A PowerShell szereti a tömbök kicsomagolását vagy számbavételét. Ez a PowerShell folyamathasználatának egyik alapvető szempontja, de vannak olyan esetek, amikor nem szeretné, hogy ez megtörténjen.

Én általában pipe objektumok, hogy Get-Member többet tudjon róluk. Amikor egy tömböt átirányítok hozzá, az le van bontva, és Get-Member a tömb tagjait látja, nem pedig a tényleges tömböt.

PS> $data = @('red','green','blue')
PS> $data | Get-Member
TypeName: System.String
...

A tömb kicsomagolásának megakadályozásához használhatja a parancsot Write-Output -NoEnumerate.

PS> Write-Output -NoEnumerate $data | Get-Member
TypeName: System.Object[]
...

Nekem van egy második módja, hogy inkább a hack (és megpróbálom elkerülni hackek, mint ez). A beírás előtt vesszőt helyezhet el a tömb előtt.

PS> ,$data | Get-Member
TypeName: System.Object[]
...

Tömböt ad vissza

A tömbök ilyen kibontása akkor is előfordul, ha egy függvényből kimenetet ad vissza vagy ad vissza értékeket. A tömböt akkor is lekérheti, ha a kimenetet egy változóhoz rendeli, így ez általában nem jelent problémát.

A fogás az, hogy van egy új tömb. Ha ez valaha is problémát jelent, használhatja Write-Output -NoEnumerate $array vagy return ,$array megkerülheti.

Bármi egyéb?

Tudom, hogy sok mindent el kell fogadnom. Remélem, hogy tanulsz valamit ebből a cikkből minden alkalommal, amikor elolvasod, és hogy kiderül, hogy jó referencia az Ön számára hosszú ideig. Ha hasznosnak találta, ossza meg másokkal, úgy gondolja, hogy ez hasznos lehet.

Innen azt javaslom, hogy nézd meg a hasonló post, hogy írtam a hashtables.