Array, ArrayList e Raccolte in PowerShell: Le Migliori Pratiche

Spesso, quando si scrivono script PowerShell, è necessario avere un modo per memorizzare un insieme di elementi. Un modo comune per farlo è utilizzare un array o un tipo specifico chiamato ArrayList. Ma cosa è un array in ogni caso? Un array è una struttura dati progettata per memorizzare una collezione di elementi. Questi possono includere sia tipi di elementi uguali che diversi.

Gli array sono utilizzati in molti linguaggi di programmazione diversi e PowerShell non fa eccezione. Ci sono molti modi per creare, manipolare e ottimizzare gli array. In questo articolo imparerai sugli ArrayList, Array e Collection, così come alcune best practice quando li si applica con PowerShell.

Prerequisiti/Requisiti

Dato che lavorerai solo con il linguaggio PowerShell stesso, non ci sono prerequisiti ambientali. È sufficiente disporre di un PC Windows con PowerShell. Più precisamente:

  • Windows PowerShell 3 o successivo
  • .NET Framework 4.5 o successivo

Vuoi altri consigli come questo? Dai un’occhiata al mio blog personale su PowerShell su: https://nkasco.com/FriendsOfATA

Creare array con PowerShell

Ci sono molti modi diversi per creare array con PowerShell. Supponiamo di avere una lista di nomi che è necessario elaborare in qualche modo, come mostrato di seguito.

John
Susie
Jim
Johnny
Carrie

Creazione di array tramite elementi separati da virgola

Il modo più semplice per creare un array è assegnare semplicemente input noti, separati da virgola, a una variabile come mostrato di seguito.

$BasicArray = "John", "Susie", "Jim", "Johnny", "Carrie"

Se esegui il metodo GetType() disponibile su tutti gli oggetti in PowerShell, vedrai che hai creato con successo un array come indicato dalla proprietà BaseType mostrata di seguito.

PS51> $BasicArray.GetType()

IsPublic IsSerial Name                                     BaseType                                                    
-------- -------- ----                                     --------                                                    
True     True     Object[]                                 System.Array

Utilizzando l’operatore di sotto-espressione

Puoi anche creare array in PowerShell tramite un operatore di sotto-espressione. Questo concetto viene comunemente utilizzato quando non si sa quanti elementi verranno aggiunti all’array. Il risultato può contenere zero o molti elementi quando viene creato.

Osserva di seguito un array chiamato $MyArray è stato creato senza elementi al suo interno.

#Crea un array vuoto con l'operatore di sotto-espressione
PS51> $MyArray = @()
PS51> $MyArray.count
0

Utilizzando l’operatore di intervallo

Gli array non sono limitati a memorizzare solo stringhe come mostrato in precedenza. Puoi anche creare array con altri tipi di oggetti come interi.

Se hai bisogno di un array di interi in ordine sequenziale, puoi fare una scorciatoia e utilizzare l’operatore di intervallo ... Di seguito puoi vedere che è stato creato un array con gli interi da 2 a 5 con una sola riga di codice.

PS51> $NumberedArray = 2..5
PS51> $NumberedArray
2
3
4
5

Creazione di collezioni ArrayList in PowerShell

Utilizzare un ArrayList di PowerShell è anche un modo in cui puoi memorizzare un elenco di elementi con PowerShell. La classe ArrayList fa parte dello spazio dei nomi System.Collections all’interno di .NET. Creando un nuovo oggetto di questo tipo, è possibile quindi memorizzare oggetti all’interno di un ArrayList.

Di seguito puoi vedere che è necessario creare esplicitamente un oggetto ArrayList utilizzando il cmdlet New-Object o convertendo un array standard in un oggetto ArrayList.

Si noti che in questo caso il BaseType è un oggetto, mentre gli esempi precedenti hanno BaseTypes di Array che mostrano l’ereditarietà dalla classe Object. In definitiva, PowerShell fornisce accesso al sistema di tipi .NET.

PS51> $MyArrayList = New-Object -TypeName "System.Collections.ArrayList"
# Convertire un array in un ArrayList è anche un'opzione valida
PS51> $MyArrayList = [System.Collections.ArrayList]@()
PS51> $MyArrayList.GetType()

IsPublic IsSerial Name                                     BaseType                                                    
-------- -------- ----                                     --------                                                    
True     True     ArrayList                                System.Object

Aggiunta di elementi a un array

Quando si crea un array, è possibile definire tutti gli elementi durante la creazione o aggiungerli ad-hoc.

Per aggiungere elementi a una collezione esistente, è possibile utilizzare l’operatore += o il metodo Add. Ma si tenga presente che ci sono differenze significative nel modo in cui operano.

Quando si crea un array standard con @(), si utilizzerà l’operatore +=, ma per aggiungere elementi a un ArrayList, si utilizzerà il metodo Add. Questi metodi differiscono nel senso che l’operatore += in realtà distrugge l’array esistente e ne crea uno nuovo con il nuovo elemento.

Per dimostrare, vedrai di seguito che puoi fare riferimento alla proprietà IsFixedSize per un array o ArrayList per sapere quale è immutabile e quale non lo è.

PS51> $BasicArray.IsFixedSize
True

PS51> $MyArrayList.IsFixedSize
False

In quanto array di base è una collezione di dimensione fissa, non è possibile modificarlo.

Tentare di utilizzare il metodo Add() con un array di dimensione fissa comporterà un errore a causa della dimensione fissa. Di seguito puoi vedere alcuni esempi in cui puoi aggiungere elementi a un array con successo.

#Non funziona
$BasicArray.Add("Nate")

#Funziona
$BasicArray += "Nate"
$MyArrayList.Add("Nate")
$MyArrayList += "Nate"

Rimozione degli elementi da un array

Ora che hai una migliore comprensione di come aggiungere elementi a un array, vediamo alcuni modi per rimuovere elementi da un array.

Poiché un array di base è fisso, non è possibile rimuovere elementi da esso. Invece, devi creare un array completamente nuovo. Ad esempio, puoi rimuovere un singolo elemento da un array creando una condizione che corrisponda solo agli elementi che desideri includere. Di seguito è mostrato un esempio.

$NewBasicArray = $BasicArray -ne "Nate"

Poiché un ArrayList non è fisso, puoi rimuovere elementi da esso utilizzando il metodo Remove(). Questo è uno scenario in cui l’uso di un ArrayList può essere vantaggioso se prevedi di aggiungere/rimuovere frequentemente elementi.

$MyArrayList.Remove("Nate")

Recupero di elementi specifici da un array o ArrayList

Per recuperare elementi specifici da un array o ArrayList, puoi utilizzare molti metodi diversi. Come altri oggetti in PowerShell, puoi accedere a tutti gli elementi di un array chiamando semplicemente l’oggetto.

PS51> $BasicArray
John
Susie
Jim
Johnny
Carrie

Forse hai bisogno di recuperare solo il primo elemento, gli array avranno sempre un’origine 0 che rappresenta il primo elemento dell’array. Per recuperare il primo elemento di un array, specifica il numero di indice tra parentesi quadre come mostrato di seguito.

PS51> $BasicArray[0]
John

Al contrario, è possibile fare riferimento agli indici all’indietro utilizzando il trattino (indicatore negativo) per richiamare gli ultimi X elementi dell’array. Un modo comune per trovare l’ultimo elemento di un array è utilizzare -1 come mostrato di seguito.

PS51> $BasicArray[-1]
Carrie

L’operatore di intervallo che hai appreso in precedenza può anche essere utilizzato per recuperare oggetti di un array seguendo lo stesso metodo di chiamata degli elementi. Supponiamo che si vogliano recuperare i primi quattro nomi nell’array $BasicArray.

Come puoi vedere di seguito, puoi specificare un intervallo di indici da 0 a 3 che restituirà i primi quattro elementi.

PS51> $BasicArray[0..3]
John
Susie
Jim
Johnny

Ottimizzazione degli array con PowerShell

Ora che hai una buona base su come creare e manipolare gli array, quale dovresti usare? Per rispondere a questa domanda, vediamo alcuni esempi con il cmdlet Measure-Command. Utilizzando il cmdlet Measure-Command, comprenderai meglio quanto tempo impiegano i comandi per elaborare gli elementi mentre vengono passati nel flusso di lavoro.

In generale, se hai una piccola collezione di oggetti, è probabile che non noterai molte differenze nel modo in cui manipoli gli array. Tuttavia, se hai una grande collezione di oggetti, è importante comprendere le differenze per ottenere risultati ottimali.

Applichiamo quanto hai appena appreso nella sezione precedente sulla differenza tra += e l’utilizzo del metodo Add() con un ciclo di 50.000 elementi.

Prima di tutto, crea un array vuoto e un ArrayList vuoto come mostrato di seguito.

PS51> $MyArray = @()
PS51> $MyArrayList = [System.Collections.ArrayList]@()

Successivamente, popola 50.000 elementi in ciascuna collezione utilizzando l’operatore di intervallo e un ciclo foreach come mostrato di seguito.

@(0..50000).foreach({$MyArray += $_})
@(0..50000).foreach({$MyArrayList.Add($_)})

Infine, incapsula i tuoi comandi in un’espressione e passa questa espressione al cmdlet Measure-Command. Eseguendo l’espressione con Measure-Command, puoi vedere quanto tempo effettivamente impiega ciascun processo per essere eseguito.

Ricorda che, come hai imparato in precedenza, += crea effettivamente un nuovo array anziché aggiungere a uno già esistente.

PS51> Measure-Command -Expression {@(0..50000).foreach({$MyArray += $_})}
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 59
Milliseconds      : 58
Ticks             : 590585963
TotalDays         : 0.000683548568287037
TotalHours        : 0.0164051656388889
TotalMinutes      : 0.984309938333333
TotalSeconds      : 59.0585963
TotalMilliseconds : 59058.5963

PS51> Measure-Command -Expression {@(0..50000).foreach({$MyArrayList.Add($_)})}
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 139
Ticks             : 1399989
TotalDays         : 1.62035763888889E-06
TotalHours        : 3.88885833333333E-05
TotalMinutes      : 0.002333315
TotalSeconds      : 0.1399989
TotalMilliseconds : 139.9989

Il risultato? Quasi 60 secondi rispetto a 139 millisecondi!

Come puoi vedere, è molto più veloce sfruttare un ArrayList per grandi collezioni anziché utilizzare un array di dimensioni fisse.

Sebbene questo sia un esempio di base, sottolinea l’importanza di comprendere cosa fa il tuo codice durante l’elaborazione. Se non viene compreso correttamente, può comportare un’esperienza utente negativa.

Se hai uno script esistente che potrebbe trarre vantaggio dall’utilizzo di un ArrayList anziché di un array, questa sarebbe un’ottima occasione per apportare un miglioramento immediato!

Ulteriori letture

Vuoi altri consigli come questo? Dai un’occhiata al mio blog personale su PowerShell su: https://nkasco.com/FriendsOfATA.

Source:
https://adamtheautomator.com/powershell-array/