Поделиться через


about_Arrays

Краткое описание

Описывает массивы, которые представляют собой структуры данных, предназначенные для хранения коллекций элементов.

Подробное описание

Массив — это структура данных, предназначенная для хранения коллекции элементов. Элементы могут быть одного или разного типа.

Начиная с Windows PowerShell 3.0 коллекция, состоящая из нуля или одного объекта, имеет некоторые свойства массивов.

Создание и инициализация массива

Чтобы создать и инициализировать массив, назначьте переменной несколько значений. Значения, хранящиеся в массиве, разделяются запятой и отделяются от имени переменной оператором присваивания (=).

Например, чтобы создать массив с именем $A , содержащий семь числовых значений (int) 22, 5, 10, 8, 12, 9 и 80, введите следующее:

$A = 22,5,10,8,12,9,80

Запятая также может использоваться для инициализации массива отдельных элементов, поместив запятую перед отдельным элементом.

Например, чтобы создать один массив элементов с именем $B , содержащим одно значение 7, введите:

$B = ,7

Вы также можете создать и инициализировать массив с помощью оператора диапазона (..). В следующем примере создается массив, содержащий значения от 5 до 8.

$C = 5..8

В результате $C содержит четыре значения: 5, 6, 7 и 8.

Если тип данных не указан, PowerShell создает каждый массив в виде массива объектов (System.Object[]). Чтобы определить тип данных массива, используйте метод GetType(). Например, чтобы определить тип данных массива, введите $A :

$A.GetType()

Чтобы создать строго типизированный массив, то есть массив, который может содержать только значения определенного типа, приведите переменную к типу массива, например string[], long[] или int32[]. Чтобы привести массив, предварите имя переменной тип массива, заключенный в квадратные скобки. Например, чтобы создать 32-разрядный массив целых чисел с именем $ia , содержащий четыре целых числа (1500, 2230, 3350 и 4000), введите:

[int32[]]$ia = 1500,2230,3350,4000

В результате $ia массив может содержать только целые числа.

Вы можете создавать массивы, которые приведены к любому поддерживаемому типу в .NET. Например, объекты, извлекаемые Get-Process для представления процессов, относятся к типу System.Diagnostics.Process . Чтобы создать строго типизированный массив объектов процесса, введите следующую команду:

[Diagnostics.Process[]]$zz = Get-Process

Оператор под-выражения массива

Оператор вложенного выражения массива создает массив из инструкций внутри него. Независимо от того, что создает оператор внутри оператора, оператор поместит его в массив. Даже если объект равен нулю или одному объекту.

Синтаксис оператора массива выглядит следующим образом:

@( ... )

Оператор array можно использовать для создания массива с нулевым или одним объектом. Пример:

$a = @("Hello World")
$a.Count
1
$b = @()
$b.Count
0

Оператор массива полезен в скриптах при получении объектов, но не знает, сколько объектов вы получаете. Пример:

$p = @(Get-Process Notepad)

Дополнительные сведения об операторе под-выражения массива см. в разделе about_Operators.

Доступ к элементам массива и их использование

Чтение массива

Вы можете ссылаться на массив, используя его имя переменной. Чтобы отобразить все элементы в массиве, введите имя массива. Например, предположим, что $a является массивом, содержащим целые числа 0, 1, 2, до 9; введите:

$a
0
1
2
3
4
5
6
7
8
9

Вы можете ссылаться на элементы в массиве, используя индекс, начинающийся с позиции 0. Заключите номер индекса в квадратные скобки. Например, чтобы отобразить первый элемент в массиве, введите $a :

$a[0]
0

Чтобы отобразить третий элемент в массиве, введите $a :

$a[2]
2

Часть массива можно получить с помощью оператора range для индекса. Например, чтобы получить второй-пятый элементы массива, введите:

$a[1..4]
1
2
3
4

Число отрицательных чисел от конца массива. Например, "-1" относится к последнему элементу массива. Чтобы отобразить последние три элемента массива, в порядке возрастания индекса введите:

$a = 0 .. 9
$a[-3..-1]
7
8
9

Если вы вводите отрицательные индексы в порядке убывания, выходные данные изменяются.

$a = 0 .. 9
$a[-1..-3]
9
8
7

Однако будьте осторожны при использовании этой нотации. Нотация циклически от конечной границы до начала массива.

$a = 0 .. 9
$a[2..-2]
2
1
0
9
8

Кроме того, одной распространенной ошибкой является предположение, что $a[0..-2] относится ко всем элементам массива, за исключением последнего. Он относится к первому, последнему и второму элементам в массиве.

Оператор плюса (+) можно использовать для объединения диапазонов со списком элементов в массиве. Например, чтобы отобразить элементы в позициях индекса от 0, 2 и 4 до 6, введите:

$a = 0 .. 9
$a[0,2+4..6]
0
2
4
5
6

Кроме того, для перечисления нескольких диапазонов и отдельных элементов можно использовать оператор "плюс". Например, чтобы перечислить элементы с нуля до двух, от четырех до шести и элемента в восьмом позициональном типе:

$a = 0..9
$a[+0..2+4..6+8]
0
1
2
4
5
6
8

Итерации по элементам массива

Вы также можете использовать конструкции цикла, такие как ForEachциклы , Forи While , для ссылки на элементы в массиве. Например, чтобы использовать ForEach цикл для отображения элементов в массиве $a , введите:

$a = 0..9
foreach ($element in $a) {
  $element
}
0
1
2
3
4
5
6
7
8
9

Цикл Foreach выполняет итерацию по массиву и возвращает каждое значение в массиве до достижения конца массива.

Цикл For полезен при приращении счетчиков при проверке элементов в массиве. Например, чтобы использовать For цикл для возврата всех остальных значений в массиве, введите:

$a = 0..9
for ($i = 0; $i -le ($a.length - 1); $i += 2) {
  $a[$i]
}
0
2
4
6
8

Вы можете использовать While цикл для отображения элементов в массиве до тех пор, пока определенное условие не перестанет выполняться. Например, чтобы отобразить элементы в массиве $a , когда индекс массива меньше 4, введите:

$a = 0..9
$i=0
while($i -lt 4) {
  $a[$i]
  $i++
}
0
1
2
3

Свойства массивов

Count, Length или LongLength

Чтобы определить, сколько элементов находится в массиве Length , используйте свойство или его Count псевдоним. Функция Longlength полезна, если массив содержит более 2 147 483 647 элементов.

$a = 0..9
$a.Count
$a.Length
10
10

Rank

Возвращает число измерений в массиве. Большинство массивов в PowerShell имеют только одно измерение. Даже если вы думаете, что создаете многомерный массив, как показано в следующем примере:

$a = @(
  @(0,1),
  @("b", "c"),
  @(Get-Process)
)

"`$a rank: $($a.Rank)"
"`$a length: $($a.Length)"
"`$a[2] length: $($a[2].Length)"
"Process `$a[2][1]: $($a[2][1].ProcessName)"

В этом примере создается одномерный массив, содержащий другие массивы. Это также называется массивом с неровным массивом. Свойство Rank доказало, что это одномерное. Чтобы получить доступ к элементам в массиве с массивом, индексы должны быть заключены в отдельные скобки ([]).

$a rank: 1
$a length: 3
$a[2] length: 348
Process $a[2][1]: AcroRd32

Многомерные массивы хранятся в основном порядке строк. В следующем примере показано, как создать действительно многомерный массив.

[string[,]]$rank2 = [string[,]]::New(3,2)
$rank2.rank
$rank2.Length
$rank2[0,0] = 'a'
$rank2[0,1] = 'b'
$rank2[1,0] = 'c'
$rank2[1,1] = 'd'
$rank2[2,0] = 'e'
$rank2[2,1] = 'f'
$rank2[1,1]
2
6
d

Чтобы получить доступ к элементам в многомерном массиве, разделяйте индексы с помощью запятой (,) в одном наборе скобок ([]).

Для некоторых операций с многомерным массивом, таких как репликация и объединение, требуется плоский массив. При сглаживания массив превращается в 1-мерный массив неограниченного типа. Полученный в результате массив принимает все элементы в построчном порядке. Рассмотрим следующий пример.

$a = "red",$true
$b = (New-Object 'int[,]' 2,2)
$b[0,0] = 10
$b[0,1] = 20
$b[1,0] = 30
$b[1,1] = 40
$c = $a + $b
$a.GetType().Name
$b.GetType().Name
$c.GetType().Name
$c

Выходные данные показывают, что $c представляет собой 1-мерный массив, содержащий элементы из $a и $b в порядке основных строк.

Object[]
Int32[,]
Object[]
red
True
10
20
30
40

Методы массивов

Clear

Устанавливает для всех значений элементов значение по умолчанию для типа элемента массива. Метод Clear() не сбрасывает размер массива.

В следующем примере $a представляет собой массив объектов .

$a = 1, 2, 3
$a.Clear()
$a | % { $null -eq $_ }
True
True
True

В этом примере $intA явно типируется для хранения целых чисел.

[int[]] $intA = 1, 2, 3
$intA.Clear()
$intA
0
0
0

ForEach

Позволяет выполнять итерацию по всем элементам в массиве и выполнять определенную операцию для каждого элемента массива.

Метод ForEach имеет несколько перегрузок, которые выполняют различные операции.

ForEach(scriptblock expression)
ForEach(scriptblock expression, object[] arguments)
ForEach(type convertToType)
ForEach(string propertyName)
ForEach(string propertyName, object[] newValue)
ForEach(string methodName)
ForEach(string methodName, object[] arguments)

ForEach(выражение scriptblock)

ForEach(выражение scriptblock, аргументы object[]

Этот метод был добавлен в PowerShell версии 4.

Примечание

Синтаксис требует использования блока скрипта. Круглые скобки являются необязательными, если scriptblock является единственным параметром. Кроме того, между методом и открывающей скобкой или фигурной скобкой не должно быть пробела.

В следующем примере показано, как использовать ForEach метод . В этом случае целью является создание квадратного значения элементов в массиве.

$a = @(0 .. 3)
$a.ForEach({ $_ * $_})
0
1
4
9

Как и в случае с -ArgumentList параметром , параметр позволяет передавать массив аргументов в блок скрипта ForEach-Object, arguments настроенный для их принятия.

Дополнительные сведения о поведении ArgumentList см. в разделе about_Splatting.

ForEach(тип convertToType)

Метод ForEach можно использовать для быстрого приведения элементов к другому типу. В следующем примере показано, как преобразовать список строковых дат в [DateTime] тип.

@("1/1/2017", "2/1/2017", "3/1/2017").ForEach([datetime])

Sunday, January 1, 2017 12:00:00 AM
Wednesday, February 1, 2017 12:00:00 AM
Wednesday, March 1, 2017 12:00:00 AM

ForEach(string propertyName)

ForEach(string propertyName, object[] newValue)

Метод ForEach также можно использовать для быстрого получения или задания значений свойств для каждого элемента в коллекции.

# Set all LastAccessTime properties of files to the current date.
(dir 'C:\Temp').ForEach('LastAccessTime', (Get-Date))
# View the newly set LastAccessTime of all items, and find Unique entries.
(dir 'C:\Temp').ForEach('LastAccessTime') | Get-Unique
Wednesday, June 20, 2018 9:21:57 AM

ForEach(string methodName)

ForEach(string methodName, object[] arguments)

LastТаким образом, ForEach методы можно использовать для выполнения метода для каждого элемента в коллекции.

("one", "two", "three").ForEach("ToUpper")
ONE
TWO
THREE

Как и в случае с -ArgumentList параметром , параметр позволяет передавать массив значений в блок скрипта ForEach-Object, Arguments настроенный для их принятия.

Примечание

Начиная с Windows PowerShell 3.0 получение свойств и выполнение методов для каждого элемента в коллекции также можно выполнять с помощью метода скалярных объектов и коллекций. Дополнительные сведения об этом см. здесь about_methods.

Where

Позволяет фильтровать или выбирать элементы массива. Скрипт должен иметь значение, отличное от нуля (0), пустой строки или $null элемента, $false отображаемого Whereпосле . Дополнительные сведения о логической оценке см. в разделе about_Booleans.

Существует одно определение метода Where .

Where(scriptblock expression[, WhereOperatorSelectionMode mode
                            [, int numberToReturn]])

Примечание

Синтаксис требует использования блока скрипта. Круглые скобки являются необязательными, если scriptblock является единственным параметром. Кроме того, между методом и открывающей скобкой или фигурной скобкой не должно быть пробела.

Параметр Expression является scriptblock, который требуется для фильтрации, mode необязательный аргумент разрешает дополнительные возможности выбора, а numberToReturn необязательный аргумент позволяет ограничить количество элементов, возвращаемых из фильтра.

Допустимые значения для mode :

  • Default (0) — возврат всех элементов
  • First (1) — возврат первого элемента
  • Last (2) — возврат последнего элемента
  • SkipUntil (3) — пропускать элементы, пока условие не будет true, возвращает все остальные элементы (включая первый элемент, для которого условие имеет значение true).
  • Until (4) — возвращает все элементы, пока условие не будет истинным.
  • Split (5) — возвращает массив из двух элементов.
    • Первый элемент содержит соответствующие элементы
    • Второй элемент содержит оставшиеся элементы

В следующем примере показано, как выбрать все нечетные числа из массива.

(0..9).Where{ $_ % 2 }
1
3
5
7
9

В этом примере показано, как выбрать непустые строки.

('hi', '', 'there').Where({$_.Length})
hi
there

Default

Режим Default фильтрует элементы с помощью Expression scriptblock.

numberToReturn Если задано значение , оно указывает максимальное количество возвращаемых элементов.

# Get the zip files in the current users profile, sorted by LastAccessTime.
$Zips = dir $env:userprofile -Recurse '*.zip' | Sort-Object LastAccessTime
# Get the least accessed file over 100MB
$Zips.Where({$_.Length -gt 100MB}, 'Default', 1)

Примечание

Default Режим и First режим возвращают первые элементы (numberToReturn) и могут использоваться взаимозаменяемо.

Last

$h = (Get-Date).AddHours(-1)
$logs = dir 'C:\' -Recurse '*.log' | Sort-Object CreationTime
# Find the last 5 log files created in the past hour.
$logs.Where({$_.CreationTime -gt $h}, 'Last', 5)

SkipUntil

Режим SkipUntil пропускает все объекты в коллекции, пока объект не пройдет фильтр выражения блока скрипта. Затем он возвращает ВСЕ оставшиеся элементы коллекции без тестирования. Тестируется только один пройденный элемент.

Это означает, что возвращенная коллекция содержит как проходящие , так и не прошедшие проверку элементы.

Количество возвращаемых элементов можно ограничить путем передачи значения аргументу numberToReturn .

$computers = "Server01", "Server02", "Server03", "localhost", "Server04"
# Find the first available online server.
$computers.Where({ Test-Connection $_ }, 'SkipUntil', 1)
localhost

Until

Режим Until инвертирует SkipUntil режим . Он возвращает ВСЕ элементы в коллекции, пока элемент не передаст выражение блока скрипта. Когда элемент передает выражение scriptblock, метод прекращает обработку Where элементов.

Это означает, что вы получаете первый набор непередаваемых элементов из Where метода . После прохождения одного элемента остальные не проверяются и не возвращаются.

Количество возвращаемых элементов можно ограничить путем передачи значения аргументу numberToReturn .

# Retrieve the first set of numbers less than or equal to 10.
(1..50).Where({$_ -gt 10}, 'Until')
# This would perform the same operation.
(1..50).Where({$_ -le 10})
1
2
3
4
5
6
7
8
9
10

Примечание

Оба Until и SkipUntil работают в локальной среде НЕ тестировать пакет элементов.

Until возвращает элементы ДО первого прохода.

SkipUntil возвращает все элементы ПОСЛЕ первого прохода, включая первый проходящий элемент.

Split

Режим Split разделяет или группирует элементы коллекции на две отдельные коллекции. Те, которые передают выражение scriptblock, и те, которые не передают.

numberToReturn Если задан , первая коллекция содержит передаваемые элементы, чтобы не превышать указанное значение.

Остальные объекты, даже те, которые передают фильтр выражений, возвращаются во второй коллекции.

$running, $stopped = (Get-Service).Where({$_.Status -eq 'Running'}, 'Split')
$running
Status   Name               DisplayName
------   ----               -----------
Running  Appinfo            Application Information
Running  AudioEndpointBu... Windows Audio Endpoint Builder
Running  Audiosrv           Windows Audio
...
$stopped
Status   Name               DisplayName
------   ----               -----------
Stopped  AJRouter           AllJoyn Router Service
Stopped  ALG                Application Layer Gateway Service
Stopped  AppIDSvc           Application Identity
...

Примечание

Оба foreach метода и where являются встроенными элементами. Дополнительные сведения о встроенных членах см . в разделе about_Instrinsic_Members

Получение элементов массива

Чтобы получить свойства и методы массива, такие как Length свойство и метод SetValue , используйте параметр InputObject командлета Get-Member .

При конвейере массива Get-Memberв PowerShell отправляет элементы по одному и Get-Member возвращает тип каждого элемента в массиве (игнорируя дубликаты).

При использовании параметра Get-MemberInputObject возвращает элементы массива.

Например, следующая команда получает элементы переменной массива $a .

Get-Member -InputObject $a

Вы также можете получить элементы массива, введя запятую (,) перед значением, которое передается в Get-Member командлет. Запятая делает массив вторым элементом в массиве массивов. PowerShell передает массивы по одному и Get-Member возвращает элементы массива. Как и в следующих двух примерах.

,$a | Get-Member

,(1,2,3) | Get-Member

Управление массивом

Вы можете изменить элементы в массиве, добавить элемент в массив и объединить значения из двух массивов в третий массив.

Чтобы изменить значение определенного элемента в массиве, укажите имя массива и индекс элемента, который требуется изменить, а затем используйте оператор присваивания (=), чтобы указать новое значение элемента. Например, чтобы изменить значение второго элемента в массиве $a (индексная позиция 1) на 10, введите:

$a[1] = 10

Для изменения значения можно также использовать метод SetValue массива. В следующем примере второе значение (позиция индекса 1) массива $a изменяется на 500:

$a.SetValue(500,1)

Оператор можно использовать для += добавления элемента в массив. В следующем примере показано, как добавить элемент в $a массив.

$a = @(0..4)
$a += 5

Примечание

При использовании += оператора PowerShell фактически создает новый массив со значениями исходного массива и добавленного значения. Это может привести к проблемам с производительностью, если операция повторяется несколько раз или размер массива слишком велик.

Удалить элементы из массива непросто, но можно создать новый массив, содержащий только выбранные элементы существующего массива. Например, чтобы создать $t массив со всеми элементами в массиве $a , кроме значения в позиции индекса 2, введите:

$t = $a[0,1 + 3..($a.length - 1)]

Чтобы объединить два массива в один массив, используйте оператор плюса (+). В следующем примере создаются два массива, объединяются и отображаются итоговые объединенные массивы.

$x = 1,3
$y = 5,9
$z = $x + $y

В результате $z массив содержит 1, 3, 5 и 9.

Чтобы удалить массив, присвойте массиву значение $null . Следующая команда удаляет массив в переменной $a .

$a = $null

Можно также использовать Remove-Item командлет , но назначение значения $null выполняется быстрее, особенно для больших массивов.

Массивы, равные нулю или единице

Начиная с Windows PowerShell 3.0 коллекция из нуля или одного объекта имеет Count свойства и Length . Кроме того, можно индексировать в массиве одного объекта. Эта функция помогает избежать ошибок скриптов, возникающих, когда команда, ожидающая коллекцию, получает менее двух элементов.

Эта функция демонстрируется в следующих примерах.

Ноль объектов

$a = $null
$a.Count
$a.Length
0
0

Один объект

$a = 4
$a.Count
$a.Length
$a[0]
$a[-1]
1
1
4
4

Поддержка индексирования для System.Tuple Объектов

В PowerShell 6.1 добавлена поддержка индексированного доступа к Tuple объектам, аналогичным массивам. Пример:

PS> $tuple = [Tuple]::Create(1, 'test')
PS> $tuple[0]
1
PS> $tuple[1]
test
PS> $tuple[0..1]
1
test
PS> $tuple[-1]
test

В отличие от массивов и других объектов коллекции, Tuple объекты обрабатываются как один объект при передаче через конвейер или с помощью параметров, поддерживающих массивы объектов .

Дополнительные сведения см. в разделе System.Tuple.

Перечисление с доступом к членам

Начиная с PowerShell 3.0, при использовании оператора доступа к членам для доступа к элементу, который не существует в коллекции списков, PowerShell автоматически перечисляет элементы в коллекции и пытается получить доступ к указанному элементу для каждого элемента. Дополнительные сведения см. в разделе about_Member-Access_Enumeration.

Примеры

В следующем примере создаются два новых файла и сохраняются результирующий объект в переменной $filesмассива . Так как объект массива не имеет Lastэлемента WriteTime , для каждого элемента в массиве возвращается значение LastWriteTime .

$files = (New-Item -Type File -Force '/temp/t1.txt'),
         (New-Item -Force -Type File '/temp/t2.txt')
$files.LastWriteTime
Friday, June 25, 2021 1:21:17 PM
Friday, June 25, 2021 1:21:17 PM

Перечисление с доступом к членам позволяет получать значения из элементов в коллекции, но не задавать значения для элементов в коллекции. Пример:

$files.LastWriteTime = (Get-Date).AddDays(-1)
InvalidOperation: The property 'LastWriteTime' cannot be found on this object.
Verify that the property exists and can be set.

Чтобы задать значения, необходимо использовать метод .

$files.set_LastWriteTime((Get-Date).AddDays(-1))
$files.LastWriteTime
Thursday, June 24, 2021 1:23:30 PM
Thursday, June 24, 2021 1:23:30 PM

Метод set_LastWriteTime() является скрытым элементом объекта FileInfo . В следующем примере показано, как найти элементы, имеющие скрытыйset метод.

$files | Get-Member | Where-Object Definition -like '*set;*'
   TypeName: System.IO.FileInfo

Name              MemberType Definition
----              ---------- ----------
Attributes        Property   System.IO.FileAttributes Attributes {get;set;}
CreationTime      Property   datetime CreationTime {get;set;}
CreationTimeUtc   Property   datetime CreationTimeUtc {get;set;}
IsReadOnly        Property   bool IsReadOnly {get;set;}
LastAccessTime    Property   datetime LastAccessTime {get;set;}
LastAccessTimeUtc Property   datetime LastAccessTimeUtc {get;set;}
LastWriteTime     Property   datetime LastWriteTime {get;set;}
LastWriteTimeUtc  Property   datetime LastWriteTimeUtc {get;set;}

Внимание!

Так как метод выполняется для каждого элемента в коллекции, следует соблюдать осторожность при вызове методов с помощью перечисления членов.

См. также раздел