Minden, amit tudni akart 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.
Feljegyzé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ézze meg a blogját a PowerShellExplained.com.
Mi a tömb?
Először egy alapszintű technikai leírással fogom kezdeni, hogy milyen tömbök vannak, és hogyan használják őket a legtöbb programozási nyelv, mielőtt a PowerShell más módon használja őket.
A tömbök olyan adatszerkezetek, amelyek több elemből álló gyűjteményként szolgálnak. A tömbön keresztül iterálhat, vagy index használatával elérheti az egyes elemeket. A tömb a memória szekvenciális adattömbjeként jön létre, ahol minden érték közvetlenül a másik mellett van tárolva.
Minden részletet meg fogok érinteni, ahogy haladunk.
Alapszintű használat
Mivel a tömbök a PowerShell egyik alapvető funkciója, létezik egy egyszerű szintaxis, amellyel a PowerShellben dolgozhat velük.
Tömb létrehozása
Üres tömb hozható létre a következő használatával: @()
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.
Több sorban deklarálhatunk tömböt. 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 több elem használata esetén nem csak könnyebben olvasható, hanem a korábbi verziókhoz képest is egyszerűbben összehasonlítható a forrásvezérlő használata esetén.
Egyéb szintaxis
Általánosan ismert, hogy @()
ez egy tömb 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'
Írási kimenet tömbök létrehozásához
Egy jó kis trükk, amit é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 sztringeket fogad el. Én soha nem csinál ez egy szkript, de ez tisztességes játék a konzolon.
Elemek elérése
Most, hogy már rendelkezik elemeket tartalmazó tömbdel, érdemes lehet elérni és frissíteni ezeket az elemeket.
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 1-et 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. Azért vezettem be ezt eltolásként, mert valójában ez az, de ezt az eltolást gyakrabban nevezik indexnek. Egy index, amely a következő időpontban 0
kezdődik: . A cikk további részében indexnek fogom hívni az eltolást.
Speciális indexelési trükkök
A legtöbb nyelvben csak egyetlen számot adhat meg indexként, és egyetlen elemet kap 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
A rendszer az elemeket a megadott indexek sorrendje alapján adja vissza. 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 eltolást végezhet a végponttól. Ha tehát a lista utolsó elemére van szüksége, használhatja -1
a következőt:
PS> $data[-1]
Three
Egy szó az óvatosságról itt az ..
operátorral. A sorrend 0..-1
és -1..0
a kiértékelés az értékekre 0,-1
és -1,0
a . Ha elfelejti ezt a részletet, könnyen láthatja $data[0..-1]
és gondolhatja, hogy az összes elemet számba venné. $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
Határon kívül
A legtöbb nyelvben, ha egy olyan elem indexét próbálja elérni, amely a tömb végén található, valamilyen hiba vagy kivétel jelenik meg. A PowerShell csendben semmit sem ad vissza.
PS> $null -eq $data[9000]
True
Null tömbbe nem indexelhető
Ha a változó tömbként $null
van indexelve, 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.
Count
A tömbök és más gyűjtemények számláló tulajdonsága jelzi, hogy hány elem van a tömbben.
PS> $data.count
4
A PowerShell 3.0 egy darabszám tulajdonságot adott hozzá a legtöbb objektumhoz. lehet egyetlen objektum, és meg kell adnia egy darab 1
.
PS> $date = Get-Date
PS> $date.count
1
Még számláló tulajdonsága is $null
van, kivéve, hogy visszaadja 0
.
PS> $null.count
0
Van néhány trap itt, hogy én majd újra, amikor foglalkozom ellenőrzése $null
, vagy üres tömbök később ebben a cikkben.
Egyenkénti 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 szeretné a második tételt, és használja az indexet 2
, és valóban kap a harmadik tétel. Vagy ha arra gondol, hogy négy elemből áll, és az utolsó elemet szeretné, így a darabszám használatával elérheti az utolsó elemet.
$data[ $data.count ]
A PowerShell tökéletesen örömmel teszi ezt, és pontosan megadja, hogy milyen elem létezik a 4. indexben: $null
. Önnek vagy a -1
fentebb megismertnek kell lennie$data.count - 1
.
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ére 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 való leállás. Ezt akkor fogom újra áttekinteni, amikor a for
hurok használatáról beszélünk.
Elemek frissítése
Ugyanezzel az indexel 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úllépő 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 áttekintem, amikor arról beszélek, hogyan lehet nagyobb tömböt létrehozni.
Iteráció
Előfordulhat, hogy egy adott ponton 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 egyes elemeihez.
Folyamat
A tömbök és a PowerShell-folyamat egymásnak vannak szánva. Ez az értékek feldolgozásának egyik legegyszerűbb módja. Amikor átad egy tömböt egy folyamatnak, a tömb minden egyes elemét egyenként dolgozza fel a rendszer.
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áttad $PSItem
, csak tudd, hogy ez ugyanaz, mint $_
. Bármelyiket használhatja, mert mindkettő a folyamat aktuális objektumát jelöli.
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 az egyszerű műveletekhez jól működik. 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 szkriptblokkot tartalmazó 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. Ez a foreach
módszer a PowerShell 4.0-ban lett hozzáadva.
A for hurok
A for
ciklust a legtöbb más nyelven erősen használják, de a PowerShellben nem sok. Ha ezt látja, az gyakran a tömbök 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 .0
Ezután hozzáadjuk azokat a feltételeket, amelyeknek $index
kisebbnek kell lenniük.$data.count
Végül azt határozzuk meg, hogy minden ciklus során növelni kell az indexet 1
. Ebben az esetben $index++
a rövid .$index = $index + 1
A formátum operátor (-f
) a kimeneti sztring értékének beszúrására $data[$index]
szolgál.
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
. Könnyen lekérheti a feltételt kissé helytelenül, ha egyszeri hibát kap a logikában. Használ, $index -le $data.count
vagy $index -lt ($data.count - 1)
mindig olyan enyhén 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.
Ciklus váltása
Ezt könnyű figyelmen kívül hagyni. Ha tömböt ad meg 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
Sok jó dolgot tehetünk a kapcsoló utasításával. 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 hurkolja őket. A fenti hurkok többsége egy változót használ a ciklusban, 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 be szeretne járni egy tömböt, és frissíteni szeretné benne az értékeket, akkor a for
ciklus 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 igénybe, módosít néhány módosítást, majd ugyanazt az indexet használja a visszaosztá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 tömbökként adja vissza az objektumok gyűjteményeit, 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, néhány részletre érdemes rámutatni.
Tulajdonságok elérése
Az index használatával 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
Általában az összes tulajdonság eléréséhez 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 felsorolja az összeset 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 nem látjuk a mögöttes összetettségét.
Where-Object filtering
Itt Where-Object
érkezik be, hogy az objektum tulajdonságai alapján szűrhessük és kiválaszthassuk, 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, hogy lekérjük a FirstName
keresett lekérdezést.
$data | Where FirstName -eq Kevin
Hol()
A tömbökben van egy Where()
metódus, 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 ciklus használata, mivel az érték cseréjéhez ismerni kell az indexet. Több lehetőségünk van az objektumokkal, mert referenciatípusok. Íme egy gyors példa:
foreach($person in $data)
{
$person.FirstName = 'Kevin'
}
Ez a hurok a tömb minden objektumát végigjárja $data
. Mivel az objektumok hivatkozástípusok, a $person
változó pontosan ugyanarra az objektumra hivatkozik, amely a tömbben található. A tulajdonságok frissítése tehát nem frissíti 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 az eredeti objektumra mutat a tömbben. Ez nem úgy működik, mint amire számított:
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éhányuk kissé másképp működik.
-Csatlakozzon
Az -join
operátor a legnyilvánvalóbb, ezért nézzük meg először. Szeretem az operátort -join
, és gyakran használom. A tömb összes elemét összekapcsolja 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 funkciója, hogy kezeli az -join
egyes elemeket.
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.
-csatlakozás $array
Itt van egy okos trükk, amit Lee Dailey mutatott nekem. Ha valaha is szeretne csatlakozni mindent nélkül elválasztó, ahelyett, hogy ezt tegye:
PS> $data = @(1,2,3,4)
PS> $data -join $null
1234
A tömböt paraméterként használhatja -join
előtag nélkül. Tekintse 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 and -split
A többi operátor szereti -replace
és -split
végrehajtja a tömb egyes elemeit. Nem mondhatom, hogy valaha is így használtam őket, 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
-Tartalmaz
Az -contains
operátor lehetővé teszi az értékek tömbjének ellenőrzését, hogy az tartalmaz-e megadott értéket.
PS> $data = @('red','green','blue')
PS> $data -contains 'green'
True
-in
Ha egyetlen értékkel rendelkezik, amelyet ellenőrizni szeretne, hogy egyezik-e a több érték egyikével, 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 is 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 bonyolulttá tehetik. Ha a tömb a bal oldalon van, minden elem össze lesz hasonlítva. A visszatérés True
helyett 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 alatt megismétlem, amikor a tesztelésről $null
beszélünk.
-Mérkőzés
Az -match
operátor megpróbálja egyeztetni a gyűjtemény egyes elemeit.
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ésadatokkal lesznek feltöltve. Nem ez a helyzet, ha egy tömböt így dolgoznak fel.
Ugyanezt a megközelítést is alkalmazhatjuk a következővel Select-String
: .
$servers | Select-String SQL
Én egy közelebbi pillantást Select-String
,-match
és a $matches
változó egy másik post nevű The many ways to use regex.
$null vagy üres
A tömbök tesztelése $null
vagy üressége bonyolult lehet. Íme a tömbök gyakori csapdái.
Ez az állítás egy pillantásra úgy tűnik, hogy működnie kell.
if ( $array -eq $null)
{
'Array is $null'
}
De most átnéztem, hogyan -eq
ellenőrzik a tömb egyes elemeit. Így több elemből álló tömb is lehet egyetlen $null értékkel, és a $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
az operátort. Ez a forgatókönyv nem probléma.
if ( $null -eq $array )
{
'Array actually is $null'
}
A $null
tömbök nem azonosak az üres tömbökéval. Ha tudja, hogy van egy tömbje, 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, amit ki kell figyelni. Akkor is használhatja az count
objektumot, ha egyetlen objektummal rendelkezik, kivéve, ha az objektum egy PSCustomObject
. Ez egy hiba, amely a PowerShell 6.1-ben van javítva.
Ez jó hír, de sokan még mindig az 5.1-en vannak, és vigyázni kell rá.
PS> $object = [PSCustomObject]@{Name='TestObject'}
PS> $object.count
$null
Ha továbbra is a PowerShell 5.1-en dolgozik, az objektumot egy tömbbe burkolhatja, mielőtt ellenőrizené a darabszámot, hogy pontos számot kapjon.
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 valakit, aki megkérdezte , 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 elgondolkozni azon, 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 hozzá kell adnia egy elemet, 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.
Feljegyzé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 List
objektumot kell használnia.
Tömb hozzáadása
Az összeadás operátort tömbökkel is használhatjuk új tömbök létrehozásához. A következő 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 a helyén, é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 PowerShell-egysorosok jutnak eszébe. A folyamatot utasításokkal és más hurkokkal foreach()
is használhatjuk. Így ahelyett, hogy elemeket adnánk hozzá egy tömbhöz egy hurokban, az elemeket a folyamatba helyezhetjük.
$array = foreach ( $node in (1..5))
{
"ATX-SQL-$node"
}
Tömbtípusok
A Rendszer alapértelmezés szerint típusként [PSObject[]]
hoz létre egy tömböt a PowerShellben. 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 beírt tömbök
Bármilyen típusú tömböt létrehozhat hasonló szintaxissal. Erősen beírt tömb létrehozásakor az 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'
ArrayList
Az elemek tömbhöz való hozzáadása az egyik legnagyobb korlátozás, de van néhány más gyűjtemény is, amelyekhez a probléma megoldásához fordulhatunk.
Ez ArrayList
általában az egyik első dolog, amire gondolunk, amikor olyan tömbre van szükségünk, amellyel gyorsabban dolgozhatunk. Úgy működik, 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')
A .NET-be hívjuk ezt a típust. Ebben az esetben az alapértelmezett konstruktort használjuk annak 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. Néhány .NET-hívás ezt teszi, és váratlan kimenetet hozhat létre.
Ha a tömbben csak sztringek vannak, akkor tekintse meg a StringBuilder használatát is. Ez szinte ugyanaz a dolog, de van néhány módszer, amely csak a sztringek kezelésére. A StringBuilder
kifejezetten teljesítményre tervezett.
Gyakran előfordul, hogy az emberek tömbökről lépnek ArrayList
át. De olyan időkbő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, akkor 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 egy ilyen 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óban található utasítással using namespace
lerövidíthetjük. 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 az adattípusok elhagyását, amikor hivatkozik rájuk.
using namespace System.Collections.Generic
$myList = [List[int]]@(1,2,3)
Így sokkal használhatóbbá válik List
.
Ön is rendelkezik hasonló Add
módszerrel. A Tömblista függvénytől eltérően nincs visszatérési érték a Add
metóduson, í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ázás[PSObject]
Bármilyen típusú listával rendelkezhet, de ha nem ismeri az objektumok típusát, [List[PSObject]]
használhatja őket az objektumok elhelyezésére.
$list = [List[PSObject]]::new()
Remove()
Az ArrayList
általános és az általános List[]
is 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 megtalálta és eltávolította az elemet a gyűjteményből.
További gyűjtemények
Sok 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, tekintse meg ezt a Mark Kraus által összeállított Gistet.
Egyéb árnyalatok
Most, hogy lefedtem az összes fő funkciót, íme néhány további dolog, amit meg akartam említeni, mielőtt becsomagolom ezt.
Előre méretezett tömbök
Említettem, hogy a tömb méretét nem módosíthatja a létrehozás után. Előre meghatározott méretű tömböt úgy hozhatunk létre, hogy meghívjuk a new($size)
konstruktorhoz.
$data = [Object[]]::new(4)
$data.count
4
Tömbök szorzása
Egy érdekes kis trükk az, hogy megszorozhat egy tömböt egész számmá.
PS> $data = @('red','green','blue')
PS> $data * 3
red
green
blue
red
green
blue
red
green
blue
Inicializálás 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 az összes nullára vonatkozik.
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 szép dolog a szorzó trükk, hogy használhat bármilyen értéket. Így ha inkább az 255
alapértelmezett érték, ez lenne a jó módja annak.
PS> $data = @(255) * 4
PS> $data
255
255
255
255
Beágyazott tömbök
A tömbön belüli tömböt 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 rácsszerű mintához hasonló módon illeszkednek.
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. Adtam egy korábbi példát egy normál tömb több sorban, ahol a vessző nem volt kötelező. A többdimenziós tömbök esetében ez nem így van.
Az index jelölésének használata kissé megváltozik most, hogy beágyazott tömböt használunk. $data
A fentiek alapján így érnénk el a 3 értéket.
PS> $outside = 0
PS> $inside = 2
PS> $data[$outside][$inside]
3
Adjon hozzá egy zárójelkészletet a tömbök beágyazásának minden szintjéhez. Az első szögletes zárójelek a külső legtöbb tömbhöz vannak, majd onnan kell befelé haladni.
Write-Output -NoEnumerate
A PowerShell szereti a tömbök kiírását vagy számbavételét. Ez a PowerShell folyamathasználatának alapvető aspektusa, de vannak olyan esetek, amikor nem szeretné, hogy ez megtörténjen.
Gyakran pipa objektumokat, hogy Get-Member
többet tudjon meg róluk. Amikor egy tömböt hozzá csövezek, az le lesz bontva, és a 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 kibontásának megakadályozásához használhatja Write-Output -NoEnumerate
a következőt: .
PS> Write-Output -NoEnumerate $data | Get-Member
TypeName: System.Object[]
...
Van egy második módja, hogy inkább egy hack (és megpróbálom elkerülni hack, mint ez). A vesszőt a tömb elé helyezheti, mielőtt becsövezené. Ez egy másik tömbbe burkolódik $data
, ahol ez az egyetlen elem, így a külső tömb kibontása után újra $data
le lesz bontva.
PS> ,$data | Get-Member
TypeName: System.Object[]
...
Tömb visszaadva
A tömbök ilyen megszüntetése akkor is előfordul, ha függvényből ad ki 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éma, használhatja Write-Output -NoEnumerate $array
vagy return ,$array
megkerülheti.
Bármi egyéb?
Tudom, hogy sok mindent be kell venni. Remélem, hogy tanulni valamit ebből a cikkből minden alkalommal, amikor elolvassa, és hogy kiderül, hogy egy jó hivatkozás az Ön számára hosszú ideig, hogy jöjjön. Ha hasznosnak találta ezt a lehetőséget, ossza meg másokkal, akikről úgy gondolja, hogy hasznos lehet belőle.
Innen azt javaslom, hogy nézd meg egy hasonló post, hogy írtam a kivonatolók.
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: