Я обнаружил интересное поведение в массивах PowerShell, а именно, если я объявлю массив следующим образом:
$array =@()
А затем попробуйте добавить элементы к нему с помощью $array.Add("item")метода, я получаю следующую ошибку:
Исключение вызывает «Добавить» с аргументом (ами) «1»: «Коллекция имела фиксированный размер».
Однако, если я добавляю элементы, используя $array += "item", элемент принимается без проблем, и ограничение «фиксированный размер», кажется, не применяется.
При использовании $array.Add()-method вы пытаетесь добавить элемент в существующий массив. Массив - это коллекция фиксированного размера, поэтому вы получите сообщение об ошибке, поскольку его невозможно расширить.
$array += $elementсоздает новый массив с теми же элементами, что и старый + новый элемент, и этот новый больший массив заменяет старый в $array-variable
Вы можете использовать оператор + =, чтобы добавить элемент в массив. Когда вы используете его, Windows PowerShell фактически создает новый массив со значениями исходного массива и добавленного значения. Например, чтобы добавить элемент со значением 200 в массив в переменной $ a, введите:
+= это дорогостоящая операция, поэтому, когда вам нужно добавить много элементов, вы должны попытаться добавить их как можно меньше операций, например:
$arr =1..3#Array
$arr +=(4..5)#Combine with another array in a single write-operation
$arr.Count5
Если это невозможно, рассмотрите возможность использования более эффективной коллекции, например Listили ArrayList(см. Другой ответ).
Спасибо :) Думал, что это может быть что-то вроде этого, но думал, что это будет неэффективно с большими массивами, поэтому команда powershell делала что-то другое.
Malgca
6
это совершенно верно, это становится неэффективным с большими массивами, к сожалению, чтобы обойти это, вы должны использовать другой тип: powershell.org/wp/2013/09/16/…
Nacht
3
Это зависит. Если вы собираетесь добавлять и удалять много участников, тогда да, попробуйте Listили ArrayList. Они будут намного быстрее. Я лично использую +=и массив 99% времени, потому что я обычно создаю короткие одноразовые сценарии, где дополнительные секунды не имеют значения. Для больших скриптов с большим количеством операций добавления / удаления, где я хочу оптимизировать и сэкономить время, которое я использую Listили ArrayList.
Фроде Ф.
3
Поскольку массивы всегда имеют фиксированный размер, кто-нибудь знает, почему Add()существует метод?
JohnLBevan
4
Потому что он унаследован от IList. Попробуй Get-Member -InputObject @()покажет этоAdd Method int IList.Add(System.Object value)
Фроде Ф.
113
Если вам нужен массив динамического размера, то вам следует составить список. Вы не только получите.Add() функциональность, но, как объясняет @ frode-f, динамические массивы более эффективны при использовании памяти и, во всяком случае, лучше.
Я попробовал это. Я создаю его, используя New-Object System.Collections.Generic.List [string], но затем, если я делаю .GetType, он говорит мне, что это массив.
Preza8
1
Вы пытались использовать Add()функцию? Я могу подтвердить, если вы создать общий Listобъект , как указано выше, у вас есть изменяемый список , для которого вы можете добавлять и удалять элементы , используя Add()и Remove()методы соответственно.
Величайший Бендер
1
@ Preza8: (New-Object System.Collections.Generic.List[string]).GetType().Nameурожайность List`1для меня, как и ожидалось; возможно, вы применили +=к переменной, содержащей список (вместо вызова .Add()метода), и в этом случае значение переменной действительно будет преобразовано в массив ( System.Object[]).
List
илиArrayList
. Они будут намного быстрее. Я лично использую+=
и массив 99% времени, потому что я обычно создаю короткие одноразовые сценарии, где дополнительные секунды не имеют значения. Для больших скриптов с большим количеством операций добавления / удаления, где я хочу оптимизировать и сэкономить время, которое я используюList
илиArrayList
.Add()
существует метод?IList
. ПопробуйGet-Member -InputObject @()
покажет этоAdd Method int IList.Add(System.Object value)
Если вам нужен массив динамического размера, то вам следует составить список. Вы не только получите
.Add()
функциональность, но, как объясняет @ frode-f, динамические массивы более эффективны при использовании памяти и, во всяком случае, лучше.И это так просто в использовании.
Вместо объявления массива попробуйте это:
Добавить предметы просто.
И если вам действительно нужен массив, когда вы закончите, для этого тоже есть функция.
источник
Add()
функцию? Я могу подтвердить, если вы создать общийList
объект , как указано выше, у вас есть изменяемый список , для которого вы можете добавлять и удалять элементы , используяAdd()
иRemove()
методы соответственно.(New-Object System.Collections.Generic.List[string]).GetType().Name
урожайностьList`1
для меня, как и ожидалось; возможно, вы применили+=
к переменной, содержащей список (вместо вызова.Add()
метода), и в этом случае значение переменной действительно будет преобразовано в массив (System.Object[]
).$a = new-object collections.generic.list[object]
Наиболее распространенная идиома для создания массива без использования неэффективного
+=
- это что-то вроде этого из вывода цикла:источник