- 10/08/2020
- 24 minuty na przeczytanie
-
- j
wszystko, co chcesz wiedzieć o macierzach
tablice są podstawową cechą większości języków programowania. Są zbiorem wartości lub przedmiotów, których trudno uniknąć. Przyjrzyjmy się z bliska tablicom i wszystkiemu, co mają do zaoferowania.,
Uwaga
Oryginalna wersja tego artykułu pojawiła się na blogu napisanym przez @KevinMarquette. Zespół ThePowerShell dziękuje Kevinowi za udostępnienie nam tych treści. Zapraszam na jego bloga atPowerShellExplained.com.
Co to jest tablica?
zacznę od podstawowego opisu technicznego, czym są tablice i jak są używane przez większość języków programowania, zanim przejdę do innych sposobów, w jaki PowerShell z nich korzysta.
tablica jest strukturą danych, która służy jako zbiór wielu elementów., Możesz iterować nad Rayem lub uzyskać dostęp do poszczególnych elementów za pomocą indeksu. Tablica jest tworzona jako sekwencyjny fragment pamięci, gdzie każda wartość jest przechowywana obok drugiej.
będę dotykał każdego z tych szczegółów, jak idziemy.
podstawowe użycie
ponieważ tablice są tak podstawową cechą PowerShell, istnieje prosta składnia do pracy z nimi w PowerShell.,
Utwórz tablicę
pustą tablicę można utworzyć za pomocą@()
PS> $data = @()PS> $data.count0
możemy utworzyć tablicę i zalążek jej wartości po prostu umieszczając je w nawiasach@()
.
PS> $data = @('Zero','One','Two','Three')PS> $data.count4PS> $dataZeroOneTwoThree
tablica ta ma 4 pozycje. Kiedy wywołujemy zmienną $data
, widzimy listę naszych pozycji. Jeśli jest ciągiem ciągów, to otrzymujemy jedną linię na ciąg.
możemy zadeklarować tablicę na wielu liniach. Przecinek jest w tym przypadku nieobowiązkowy i generalnie pominięty.,
$data = @( 'Zero' 'One' 'Two' 'Three')
wolę deklarować moje tablice na wielu liniach w ten sposób. Nie tylko staje się łatwiejszy do odczytania, gdy masz wiele pozycji, ale także ułatwia porównanie z poprzednimi wersjami podczas korzystania z sourcecontrol.
Inna składnia
powszechnie przyjmuje się, że @()
jest składnią do tworzenia tablicy, ale Listy rozdzielane przecinkami działają przez większość czasu.,
$data = 'Zero','One','Two','Three'
Write-Output to create arrays
jedna fajna sztuczka, o której warto wspomnieć, to to, że możesz użyćWrite-Output
do szybkiego tworzenia stringów w konsoli.
$data = Write-Output Zero One Two Three
jest to przydatne, ponieważ nie musisz umieszczać cudzysłowów wokół łańcuchów, gdy parametr acceptsstrings. Nigdy bym tego nie zrobił w scenariuszu, ale to uczciwa gra na konsoli.
dostęp do elementów
teraz, gdy masz tablicę z elementami w niej, możesz chcieć uzyskać dostęp i zaktualizować te elementy.,
Offset
aby uzyskać dostęp do poszczególnych elementów, używamy nawiasów z wartością offsetu zaczynającą się od 0. W ten sposób otrzymujemy pierwszą pozycję w naszej tablicy:
PS> $data = 'Zero','One','Two','Three'PS> $dataZero
powodem, dla którego używamy zero jest to, że pierwsza pozycja znajduje się na początku listy, więc używamy przesunięcia 0 pozycji, aby do niej dotrzeć. Aby dostać się do drugiego elementu, musimy użyć offsetu o 100%.
PS> $dataOne
oznaczałoby to, że ostatnia Pozycja znajduje się w offsecie 3.,
PS> $dataThree
Index
teraz możesz zobaczyć, dlaczego wybrałem wartości, które zrobiłem dla tego przykładu. Wprowadziłem to jako offsetbecause that is what it really is, ale ten offset jest częściej określany jako indeks. Anindex, który zaczyna się od 0
. W dalszej części tego artykułu nazwę offset indeksem.
specjalne sztuczki indeksowe
w większości języków możesz podać tylko jedną liczbę jako indeks, a otrzymasz z powrotem jedną pozycję.PowerShell jest znacznie bardziej elastyczny. Możesz używać wielu indeksów jednocześnie., Podając listę exexes, możemy wybrać kilka pozycji.
PS> $dataZeroTwoThree
elementy zwracane są na podstawie kolejności podanych indeksów. Jeśli zduplikujesz indeks, otrzymasz ten element za każdym razem.
PS> $dataThreeZeroThree
możemy określić ciąg liczb za pomocą wbudowanego operatora..
.
PS> $dataOneTwoThree
To działa również w odwrotnej kolejności.
PS> $dataThreeTwoOne
możesz użyć ujemnych wartości indeksu do przesunięcia od końca. Więc jeśli potrzebujesz ostatniej pozycji na liście, możesz użyć -1
.,
PS> $dataThree
Out of bounds
w większości języków, jeśli spróbujesz uzyskać dostęp do indeksu elementu, który znajduje się poza końcem tablicy, pojawi się jakiś typ błędu lub wyjątek. PowerShell po cichu nic nie zwraca.
PS> $null -eq $dataTrue
nie można indeksować do tablicy null
jeśli zmienna jest $null
I próbujesz indeksować ją jak tablicę, otrzymasz wyjątekSystem.Management.Automation.RuntimeException
z KomunikatemCannot index into a null array
.,
PS> $empty = $nullSP> $emptyError: Cannot index into a null array.
upewnij się więc, że Twoje tablice nie są$null
zanim spróbujesz uzyskać dostęp do elementów wewnątrz nich.
Count
tablice i inne kolekcje mają właściwość count, która mówi, ile elementów znajduje się w tablicy.
PS> $data.count4
PowerShell 3.0 dodał właściwość count do większości obiektów. możesz mieć pojedynczy obiekt i powinien on mieć wartość 1
.
PS> $date = Get-DatePS> $date.count1
nawet$null
ma właściwość count, z wyjątkiem tego, że zwraca0
.,
PS> $null.count0
są tu pewne pułapki, które będę ponownie sprawdzać, gdy obejmę sprawdzanie$null
lub puste arrayslater w tym artykule.
błędy Off-by-one
powstaje powszechny błąd programowania, ponieważ tablice rozpoczynają się od indeksu 0. Błędy Off-by-one można wprowadzać na dwa sposoby.
pierwszy polega na tym, że myśląc psychicznie chcesz mieć drugi element i używając indeksu2
I naprawdę getting the third element. Lub myśląc, że masz cztery elementy i chcesz ostatni element, więc używasz licznika, aby uzyskać dostęp do ostatniego elementu.,
$data
PowerShell z przyjemnością na to pozwoli i poda dokładnie, jaki element istnieje w indeksie 4: $null
. Powinieneś używać $data.count - 1
lub -1
, o których dowiedzieliśmy się powyżej.
PS> $dataThree
tutaj możesz użyć indeksu-1
aby uzyskać ostatni element.
PS> $dataThree
Lee Dailey wskazał mi również, że możemy użyć$data.GetUpperBound(0)
aby uzyskać maksymalny Numer indeksu.,
PS> $data.GetUpperBound(0)3PS> $dataThree
drugim najczęstszym sposobem jest iteracja listy i nie zatrzymywanie się we właściwym czasie. Powiem tak, gdy mówimy o użyciu pętli for
.
aktualizowanie pozycji
możemy użyć tego samego indeksu do aktualizacji istniejących pozycji w tablicy. Daje nam to bezpośredni dostęp do poszczególnych elementów.
$data = 'dos'$data = 'tres'
jeśli spróbujemy zaktualizować element, który jest poza ostatnim elementem, to otrzymamy błądIndex was outside the bounds of the array.
.
wrócę do tego później, gdy będę mówił o tym, jak powiększyć tablicę.,
iteracja
w pewnym momencie może być konieczne przejście lub iteracja całej listy i wykonanie jakiejś akcji dla każdego z nich w tablicy.
Pipeline
tablice i pipeline PowerShell są przeznaczone dla siebie. Jest to jeden z najprostszych sposobów przetworzenia tych wartości. Gdy przekazujesz tablicę do potoku, każdy element wewnątrz tablicy jest przetwarzany indywidualnie.
PS> $data = 'Zero','One','Two','Three'PS> $data | ForEach-Object {"Item: "}Item: Item: Item: Item:
Jeśli nie widziałeś$PSItem
wcześniej, po prostu wiedz, że jest to to samo, co$_
., Można użyć obu tych obiektów, ponieważ oba reprezentują bieżący obiekt w potoku.
ForEach loop
ForEach
loop dobrze współpracuje ze zbiorami. Używając składni:foreach ( <variable> in <collection> )
foreach ( $node in $data ){ "Item: "}
metoda ForEach
zazwyczaj zapominam o tej, ale działa dobrze dla prostych operacji. PowerShell pozwala na wywołanie .ForEach()
na kolekcji.
PS> $data.foreach({"Item "})Item Item Item Item
.foreach()
pobiera parametr, który jest blokiem skryptu., Możesz upuścić nawiasy i po prostu udostępnić blok skryptu.
$data.foreach{"Item "}
jest to mniej znana składnia, ale działa tak samo. Ta metodaforeach
została dodana w PowerShell 4.0.
dla pętli
for
pętla jest często używana w większości innych języków, ale nie widzisz jej zbyt często w PowerShell. Kiedy to widzisz, często jest to w kontekście chodzenia po tablicy.
for ( $index = 0; $index -lt $data.count; $index++){ "Item: " -f $data}
pierwszą rzeczą, którą robimy, jest zainicjowanie$index
do0
., Następnie dodajemy warunek, że $index
musi być mniejszy niż$data.count
. Na koniec określamy, że za każdym razem, gdy zapętlamy pętlę, muszę zwiększyć wartość indeksu o 1
. W tym przypadku $index++
jest skrótem od $index = $index + 1
.
za każdym razem, gdy używasz pętlifor
, zwróć szczególną uwagę na warunek. Użyłem tutaj$index -lt $data.count
. Łatwo jest nieco pomylić warunek, aby uzyskać off-by-oneerror w logice., Używanie $index -le $data.count
lub$index -lt ($data.count - 1)
zawsze jest źle. To spowoduje, że wynik przetworzy zbyt wiele lub zbyt mało elementów. To jest klasyczny błąd off-by-one.
pętla przełącznika
jest to taka, którą łatwo przeoczyć. Jeśli podasz tablicę do instrukcji switch, sprawdza ona każdy element w tablicy.
$data = 'Zero','One','Two','Three'switch( $data ){ 'One' { 'Tock' } 'Three' { 'Tock' } Default { 'Tick' }}
TickTockTickTock
istnieje wiele fajnych rzeczy, które możemy zrobić z instrukcją switch. Mam jeszcze jeden artykuł na ten temat.,
- wszystko, co kiedykolwiek chciałeś wiedzieć o instrukcji switch
aktualizowanie wartości
gdy Twoja tablica jest zbiorem łańcuchów lub liczb całkowitych (typów wartości), czasami możesz chcieć zmienić wartości w tablicy podczas ich pętli. Większość powyższych pętli używa zmiennej theloop, która przechowuje kopię wartości. Jeśli zaktualizujesz tę zmienną, oryginalna wartość w tablicy nie zostanie zaktualizowana.
wyjątkiem od tej instrukcji jest pętla for
., Jeśli chcesz przejść przez tablicę i zaktualizować wartości w jej pobliżu, to pętla for
jest tym, czego szukasz.
for ( $index = 0; $index -lt $data.count; $index++ ){ $data = "Item: " -f $data}
Ten przykład pobiera wartość według indeksu, wprowadza kilka zmian, a następnie używa tego samego indeksu do przypisania z powrotem.
Tablice obiektów
do tej pory jedyną rzeczą, którą umieściliśmy w tablicy jest typ wartości, ale tablice mogą również zawierać obiekty.
$data = @( @{FirstName='Kevin';LastName='Marquette'} @{FirstName='John'; LastName='Doe'})
wiele cmdletów zwraca kolekcje obiektów jako tablice po przypisaniu ich do zmiennej.,
$processList = Get-Process
wszystkie podstawowe funkcje, o których już mówiliśmy, nadal mają zastosowanie do tablic obiektów z kilkoma szczegółami, które warto wskazać.
dostęp do właściwości
możemy użyć indeksu, aby uzyskać dostęp do poszczególnych pozycji w kolekcji, tak jak w przypadku typów wartości.
PS> $dataFirstName LastName----- ----Kevin Marquette
możemy uzyskać dostęp i aktualizować właściwości bezpośrednio.,
PS> $data.FirstNameKevinPS> $data.FirstName = 'Jay'PS> $dataFirstName LastName----- ----Jay Marquette
właściwości tablicy
normalnie musisz wyliczyć całą listę w ten sposób, aby uzyskać dostęp do wszystkich właściwości:
PS> $data | ForEach-Object {$_.LastName}MarquetteDoe
lub za pomocą Select-Object -ExpandProperty
cmdlet.
PS> $data | Select-Object -ExpandProperty LastNameMarquetteDoe
ale PowerShell oferuje nam możliwość żądaniaLastName
bezpośrednio. PowerShell wylicza wszystkie dla nas i zwraca czystą listę.
PS> $data.LastNameMarquetteDoe
wyliczenie nadal się dzieje, ale nie widzimy złożoności za nim.,
Where-Object filtering
tutaj pojawia się Where-Object
, dzięki czemu możemy filtrować i wybierać to, co chcemy z tablicy na podstawie właściwości obiektu.
PS> $data | Where-Object {$_.FirstName -eq 'Kevin'}FirstName LastName----- ----Kevin Marquette
możemy napisać to samo zapytanie, aby uzyskaćFirstName
szukamy.
$data | Where FirstName -eq Kevin
gdzie ()
tablice mająWhere()
metoda na nich, która pozwala określićscriptblock
dla filtra.
$data.Where({$_.FirstName -eq 'Kevin'})
Ta funkcja została dodana w PowerShell 4.0.,
aktualizowanie obiektów w pętlach
z typami wartości, jedynym sposobem aktualizacji tablicy jest użycie pętli for, ponieważ musimy znać theindex, aby zastąpić wartość. Mamy więcej opcji z obiektami, ponieważ są to typy referencyjne. Oto krótki przykład:
foreach($person in $data){ $person.FirstName = 'Kevin'}
ta pętla przechodzi przez każdy obiekt w tablicy $data
. Ponieważ obiekty są typami referencyjnymi, zmienna$person
odwołuje się do dokładnie tego samego obiektu, który znajduje się w tablicy. Tak więc aktualizacje do itsproperties aktualizują oryginał.,
nadal nie można zastąpić w ten sposób całego obiektu. Jeśli próbujesz przypisać nowy obiekt do zmiennej$person
, aktualizujesz odniesienie do zmiennej o coś innego, co nie wskazuje już na oryginalny obiekt w tablicy. To nie działa tak, jak można się spodziewać:
foreach($person in $data){ $person = @{ FirstName='Kevin' LastName='Marquette' }}
operatory
operatory w PowerShell działają również na tablicach. Niektóre z nich działają nieco inaczej.
-join
operator-join
jest najbardziej oczywisty, więc przyjrzyjmy się mu najpierw., Lubię operatora -join
i używam go często. Łączy wszystkie elementy w tablicy z określonym znakiem lub łańcuchem znaków.
PS> $data = @(1,2,3,4)PS> $data -join '-'1-2-3-4PS> $data -join ','1,2,3,4
jedną z funkcji, które lubię w-join
operator jest to, że obsługuje pojedyncze elementy.
PS> 1 -join '-'1
używam tego wewnątrz logowania i verbose wiadomości.
PS> $data = @(1,2,3,4)PS> "Data is $($data -join ',')."Data is 1,2,3,4.
-join $array
oto sprytna sztuczka, na którą zwrócił mi uwagę Lee Dailey., Jeśli kiedykolwiek chcesz dołączyć wszystko bez ogranicznika, zamiast tego:
PS> $data = @(1,2,3,4)PS> $data -join $null1234
możesz użyć-join
z tablicą jako parametrem bez prefiksu. Spójrz na ten przykład, aby zobaczyć, o którym mówię.
PS> $data = @(1,2,3,4)PS> -join $data1234
-replace and-split
Inne operatory, takie jak-replace
I-split
wykonują na każdej pozycji w tablicy. Nie mogę powiedzieć, że kiedykolwiek używałem ich w ten sposób, ale oto przykład.,
PS> $data = @('ATX-SQL-01','ATX-SQL-02','ATX-SQL-03')PS> $data -replace 'ATX','LAX'LAX-SQL-01LAX-SQL-02LAX-SQL-03
-zawiera
operator-contains
pozwala sprawdzić tablicę wartości, aby sprawdzić, czy zawiera ona określoną wartość.
PS> $data = @('red','green','blue')PS> $data -contains 'green'True
-w
gdy masz pojedynczą wartość, którą chcesz zweryfikować, możesz użyć operatora -in
. Wartość będzie po lewej, a tablica po prawej stronie operatora.
PS> $data = @('red','green','blue')PS> 'green' -in $dataTrue
może to być drogie, jeśli lista jest duża. Często używam wzorca regex, jeśli sprawdzam więcej niż kilka wartości.,
PS> $data = @('red','green','blue')PS> $pattern = "^({0})$" -f ($data -join '|')PS> $pattern^(red|green|blue)$PS> 'green' -match $patternTrue
-eq i-ne
równość i tablice mogą być skomplikowane. Gdy tablica znajduje się po lewej stronie, każdy element jest porównywany. Zamiast zwracać True
, zwraca obiekt, który pasuje.
PS> $data = @('red','green','blue')PS> $data -eq 'green'green
Kiedy używasz operatora-ne
, otrzymujemy wszystkie wartości, które nie są równe naszej wartości.
PS> $data = @('red','green','blue')PS> $data -ne 'green'redblue
gdy używasz tego polecenia w instrukcjiif()
zwracana wartość toTrue
wartość., Jeśli nie zostanie zwrócona żadna wartość, to jest to wartość False
. Oba te następne polecenia są oceniane do True
.
$data = @('red','green','blue')if ( $data -eq 'green' ){ 'Green was found'}if ( $data -ne 'green' ){ 'And green was not found'}
wrócę do tego za chwilę, gdy porozmawiamy o testowaniu dla$null
.
-dopasuj
operator-match
próbuje dopasować każdy element w kolekcji.
PS> $servers = @( 'LAX-SQL-01' 'LAX-API-01' 'ATX-SQL-01' 'ATX-API-01')PS> $servers -match 'SQL'LAX-SQL-01ATX-SQL-01
gdy używasz-match
z pojedynczą wartością, specjalna zmienna$Matches
zostanie wypełniona matchinfo., Nie jest tak, gdy tablica jest przetwarzana w ten sposób.
możemy przyjąć to samo podejście z Select-String
.
$servers | Select-String SQL
przyjrzałem się bliżejSelect-String
,-match
I zmiennej$matches
w innym poście o nazwie wiele sposobów użycia wyrażeń regularnych.
$null lub empty
testowanie$null
lub pustych tablic może być trudne. Oto typowe pułapki z tablicami.
na pierwszy rzut oka to stwierdzenie wygląda na to, że powinno zadziałać.,
if ( $array -eq $null){ 'Array is $null'}
ale właśnie przejrzałem, jak -eq
sprawdza każdy element w tablicy. Tak więc możemy mieć tablicę kilku elementów z pojedynczą wartością $null i będzie ona oceniana na $true
$array = @('one',$null,'three')if ( $array -eq $null){ 'I think Array is $null, but I would be wrong'}
dlatego najlepiej jest umieścić$null
po lewej stronie operatora. To sprawia, że scenariusz ten nie stanowi problemu.
if ( $null -eq $array ){ 'Array actually is $null'}
a$null
tablica nie jest tym samym co pusta tablica. Jeśli wiesz, że masz tablicę, sprawdź ilość obiektów w niej zawartych., Jeśli tablica jest $null
, liczba jest 0
.
if ( $array.count -gt 0 ){ "Array isn't empty"}
jest jeszcze jedna pułapka, na którą warto uważać. Możesz użyć count
nawet jeśli masz pojedynczy obiekt, chyba że ten obiekt jest PSCustomObject
. Jest to błąd, który został naprawiony w PowerShell 6.1.To dobra wiadomość, ale wiele osób nadal jest na 5.1 i trzeba na nią uważać.
PS> $object = @{Name='TestObject'}PS> $object.count$null
Jeśli nadal korzystasz z PowerShell 5.1, możesz zawinąć obiekt w tablicę przed sprawdzeniem licznika, aby uzyskać dokładną liczbę.,
if ( @($array).count -gt 0 ){ "Array isn't empty"}
aby grać bezpiecznie, sprawdź $null
, a następnie sprawdź liczbę.
if ( $null -ne $array -and @($array).count -gt 0 ){ "Array isn't empty"}
All-eq
ostatnio widziałem, jak ktoś zapytał, Jak sprawdzić, czy każda wartość w tablicy odpowiada podanej wartości.Użytkownik Reddit / u / bis miał to sprytne rozwiązanie, które sprawdza błędne wartości, a następnie wyświetla wynik.
$results = Test-Somethingif ( -not ( $results -ne 'Passed') ){ 'All results a Passed'}
dodawanie do tablic
w tym momencie zaczynasz się zastanawiać, jak dodać elementy do tablicy. Szybka Odpowiedź jest taka, że nie możesz. tablica jest stałym rozmiarem w pamięci., Jeśli chcesz ją rozwinąć lub dodać do niej pojedynczy element, thenyou musisz utworzyć nową tablicę i skopiować wszystkie wartości ze starej tablicy. Brzmi to jak dużo pracy, jednak PowerShell ukrywa złożoność tworzenia nowej tablicy. PowerShellimplements operator dodawania (+
) dla tablic.
Uwaga
PowerShell nie implementuje operacji odejmowania. Jeśli chcesz mieć elastyczną alternatywę dla anarray, musisz użyć generycznego obiektu List
.,
dodawanie tablicy
możemy użyć operatora dodawania z tablicami do utworzenia nowej tablicy. Więc biorąc pod uwagę te dwie tablice:
$first = @( 'Zero' 'One')$second = @( 'Two' 'Three')
możemy dodać je razem, aby uzyskać nową tablicę.
PS> $first + $secondZeroOneTwoThree
Plus równa się +=
możemy utworzyć nową tablicę i dodać do niej element w następujący sposób:
$data = @( 'Zero' 'One' 'Two' 'Three')$data += 'four'
pamiętaj, że za każdym razem, gdy używasz +=
że duplikujesz i tworzysz nową tablicę / align = „left” / To nie jest problem dla małych zbiorów danych, ale skaluje się bardzo słabo.,
przypisanie potoku
możesz przypisać wyniki dowolnego potoku do zmiennej. Jest tablicą, jeśli zawiera multipleitems.
$array = 1..5 | ForEach-Object { "ATX-SQL-$PSItem"}
zwykle, gdy myślimy o użyciu potoku, myślimy o typowych jednowierszowych PowerShell. Potoku możemy użyć foreach()
I innych pętli. Więc zamiast dodawać elementy do anarray w pętli, możemy upuścić elementy do potoku.
$array = foreach ( $node in (1..5)){ "ATX-SQL-$node"}
typy tablic
domyślnie tablica w PowerShell jest tworzona jako typ]
., Dzięki temu może zawierać dowolne typy obiektów lub wartości. To działa, ponieważ wszystko jest dziedziczone z typu PSObject
.
Tablice silnie wpisywane
możesz utworzyć tablicę dowolnego typu używając podobnej składni. Tablica silnie wpisana może zawierać tylko wartości lub obiekty określonego typu.
ArrayList
dodawanie elementów do tablicy jest jednym z jej największych ograniczeń, ale istnieje kilka innych kolekcji, do których możemy się zwrócić, aby rozwiązać ten problem.,
ArrayList
jest powszechnie jedną z pierwszych rzeczy, które myślimy, gdy potrzebujemy tablicy, z którą isfaster do pracy. Działa jak tablica obiektów w każdym miejscu, w którym jej potrzebujemy, ale szybko obsługuje dodawanie elementów.
oto jak tworzymy ArrayList
I dodajemy do niego elementy.
$myarray = ::new()$myArray.Add('Value')
wywołujemy.NET, aby uzyskać ten typ. W tym przypadku używamy domyślnego konstruktora, aby go utworzyć. Następnie wywołujemy metodę Add
aby dodać do niej element.,
powodem, dla którego używam na początku linii jest wyłączenie kodu zwrotnego. Some.NET wywołania robią to i mogą tworzyć nieoczekiwane wyjście.
Jeśli jedyne dane, które masz w swojej tablicy, to StringBuilder. To prawie to samo, ale ma kilka metod, które są tylko do radzenia sobie zstrings. StringBuilder
jest specjalnie zaprojektowany dla wydajności.
często zdarza się, że ludzie przechodzą doArrayList
z tablic. Ale pochodzi z czasów, w których C# nie miało ogólnego wsparcia., ArrayList
jest przestarzały w obsłudze generycznej List
lista generyczna
Typ generyczny jest specjalnym typem w C#, który definiuje uogólnioną klasę, A użytkownik określa typy danych, których używa podczas tworzenia. Więc jeśli chcesz listę liczb lub ciągów znaków, możesz określić, że chcesz listę typówint
lubstring
.
oto jak tworzysz listę ciągów.
$mylist = ]::new()
lub lista liczb.,
$mylist = ]::new()
możemy wrzucić istniejącą tablicę do takiej listy bez uprzedniego tworzenia obiektu:
$mylist = ]@(1,2,3)
możemy skrócić składnię za pomocą instrukcjiusing namespace
w PowerShell 5 i nowszych. Instrukcjausing
musi być pierwszą linią skryptu. Deklarując przestrzeń nazw, Powershellets pozostawić go poza typami danych podczas odwoływania się do nich.
using namespace System.Collections.Generic$myList = ]@(1,2,3)
To sprawia, żeList
jest znacznie bardziej użyteczny.,
masz do dyspozycji podobnąAdd
metodę. W przeciwieństwie do ArrayList, nie ma zwracanej wartości Add
metoda więc nie musimy void
to.
$myList.Add(10)
i nadal możemy uzyskać dostęp do elementów jak inne tablice.
PS> $myList10
lista
możesz mieć listę dowolnego typu, ale jeśli nie znasz typu obiektów, możesz użyć]
, aby je zawierać.,
$list = ]::new()
Usuń ()
ArrayList
I ogólnyList
oba obsługują usuwanie elementów z kolekcji.
using namespace System.Collections.Generic$myList = ]@('Zero','One','Two','Three')$myList.Remove("Two")ZeroOneThree
podczas pracy z typami wartości usuwa pierwszy z listy. Możesz go nazywać w kółko, aby nadal usuwać tę wartość. Jeśli masz typy referencyjne, musisz podać obiekt, który chcesz usunąć.,
]$drives = Get-PSDrive$drives.remove($drives)
$delete = $drives$drives.remove($delete)
metoda remove zwracatrue
jeśli udało się znaleźć i usunąć element z kolekcji.
więcej kolekcji
istnieje wiele innych kolekcji, które mogą być używane, ale są to dobre zamienniki generycznych tablic.Jeśli jesteś zainteresowany poznaniem Więcej z tych opcji, spójrz na thisGist, że marka Kraus ułożyła razem.
inne niuanse
teraz, gdy omówiłem wszystkie główne funkcje, oto kilka innych rzeczy, które chciałem zrobić, zanim to zakończę.,
Pre-size tablic
wspomniałem, że nie można zmienić rozmiaru tablicy po jej utworzeniu. Możemy utworzyć tablicę o wstępnie ustalonym rozmiarze, wywołując ją konstruktoremnew($size)
.
$data = ]::new(4)$data.count4
mnożenie tablic
ciekawa sztuczka polega na tym, że można pomnożyć tablicę przez liczbę całkowitą.
PS> $data = @('red','green','blue')PS> $data * 3redgreenblueredgreenblueredgreenblue
Inicjalizuj za pomocą 0
powszechnym scenariuszem jest utworzenie tablicy ze wszystkimi zerami. Jeśli będziesz mieć tylko liczby całkowite, silnie wpisana tablica liczb całkowitych domyślnie zawiera wszystkie zera.,
PS> ]::new(4)0000
w tym celu możemy użyć sztuczki z mnożeniem.
PS> $data = @(0) * 4PS> $data0000
fajną rzeczą w sztuczce z mnożeniem jest to, że możesz użyć dowolnej wartości. Jeśli więc zamiast domyślnej wartości masz 255
, to jest to dobry sposób, aby to zrobić.
PS> $data = @(255) * 4PS> $data255255255255
zagnieżdżone tablice
tablica wewnątrz tablicy nazywa się zagnieżdżoną tablicą. Nie używam ich dużo w PowerShell, ale używam ich więcej w innych językach. Rozważ użycie tablicy tablic, gdy dane pasują do wzorca gridlike.,
oto dwa sposoby na stworzenie tablicy dwuwymiarowej.
$data = @(@(1,2,3),@(4,5,6),@(7,8,9))$data2 = @( @(1,2,3), @(4,5,6), @(7,8,9))
przecinek jest bardzo ważny w tych przykładach. Podałem wcześniejszy przykład zwykłej tablicy na wielu liniach, gdzie przecinek był opcjonalny. Tak nie jest w przypadku wielowymiarowej tablicy.
sposób, w jaki używamy notacji indeksu zmienia się nieco teraz, gdy mamy zagnieżdżoną tablicę. Używając$data
powyżej, uzyskamy dostęp do wartości 3.
PS> $outside = 0PS> $inside = 2PS> $data3
Dodaj zestaw nawiasów dla każdego poziomu zagnieżdżania tablicy., Pierwszy zestaw nawiasów jest dla najbardziej wysuniętej tablicy, a następnie wchodzi się stamtąd.
Write-Output-NoEnumerate
PowerShell lubi rozpakowywać lub wyliczać tablice. Jest to podstawowy aspekt sposobu, w jaki PowerShell używa thepipeline, ale są chwile, w których nie chcesz, aby tak się stało.
Zwykle przesyłam obiekty doGet-Member
, aby dowiedzieć się więcej o nich. Kiedy przesyłam do niej tablicę, to ją rozpakowuję I Get-Member widzi członków tablicy, a nie rzeczywistą tablicę.,
PS> $data = @('red','green','blue')PS> $data | Get-MemberTypeName: System.String...
aby zapobiec rozpakowaniu tablicy, możesz użyć Write-Object -NoEnumerate
.
PS> Write-Output -NoEnumerate $data | Get-MemberTypeName: System.Object...
mam drugi sposób, który jest bardziej hack (i staram się unikać hacków takich jak ten). Możesz umieścić acomma przed tablicą przed rurką.
PS> ,$data | Get-MemberTypeName: System.Object...
zwraca tablicę
to rozpakowywanie tablic ma miejsce również wtedy, gdy wypisujesz lub zwracasz wartości z funkcji. Możesz uzyskać tablicę, jeśli przypisujesz wyjście do zmiennej, więc nie jest to zwykle problem.
haczyk polega na tym, że masz nową tablicę., Jeśli jest to kiedykolwiek problem, możesz użyćWrite-Output -NoEnumerate $array
lub return ,$array
, aby obejść ten problem.
Dodaj komentarz