Azely
Azely

Reputation: 77

PowerShell function for adding elements to an array

I'm still quite new to PowerShell and am trying to create a few functions that weaves together for creating and administrating an array. And I'm having some problems with getting one of these functions to work as intended.

I need the second function (AddToArray) to add an element to the specified index. None of the existing elements can be overwritten or removed.

For example, if I have an array with four indexes and all have the value 5 and I call the function AddToArray 2 4. I need the function to write for in the third index and move the existing ones one down step, so the array now looks like this:

5
5
4
5
5

This is my code so far that shows my CreateArray function and the little code piece for AddToArray function. I've been trying for a while now, but I just can't see the solution.

function CreateArray($Item1, $Item2)
{
    $arr = New-Object Array[] $Item1;

    # Kontrollerar om $Item2 har fått någon input och skriver in det i arrayen
    if ($Item2)
    {
        for($i = 0; $i -lt $arr.length; $i++)
        {
            $arr[$i] = $Item2;
        }
    }
    # Standard värde på arrayens index om inget värde anges vid funktionens anrop
    else
    {
        $Item2 = "Hej $env:username och välkommen till vårat script!";

        for($i = 0; $i -lt $arr.length; $i++)
        {
            $arr[$i] = $Item2;
        }
    }
    $script:MainArray = $arr;
}

function AddToArray ($index, $add)
{
    $MainArray[$index] = $add;
}

Upvotes: 1

Views: 4229

Answers (2)

mjolinor
mjolinor

Reputation: 68273

Arrays don't have an .insert() method, but collections do. An easy way to produce a collection from an array is to use the .invoke() method of scriptblock:

$array = 5,5,4,5,5

$collection = {$array}.invoke()
$collection
$collection.GetType()

5
5
4
5
5

IsPublic IsSerial Name                                     BaseType                                  
-------- -------- ----                                     --------                                  
True     True     Collection`1                             System.Object                             

Now you can use the .insert() method to insert an element at an arbitrary index:

$collection.Insert(2,3)
$collection


5
5
3
4
5
5

If you need it to be an array again, an easy way to convert it back to an array is to use the pipeline:

$collection | set-variable array
$array
$array.GetType()

5
5
3
4
5
5

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

Upvotes: 0

Keith Hill
Keith Hill

Reputation: 201652

Arrays in .NET don't directly support insertion and they are normally fixed size. PowerShell does allow for easy array resizing but if the array gets large and you're appending (causing a resize) a lot, the performance can be bad.

One easy way to do what you want is to create a new array from the pieces e.g.:

if ($index -eq 0) {
    $MainArray = $add,$MainArray
}
elseif ($index -eq $MainArray.Count - 1) {
    $MainArray += $add
}
else {
    $MainArray = $MainArray[0..($index-1)], $add, $MainArray[$index..($MainArray.Length-1)]
}

But that is kind of a spew. I would use a List for this, which supports insertion and is more efficient than an array.

$list = new-object 'System.Collections.Generic.List[object]'
$list.AddRange((1,2,3,4,5))
$list.Insert(2,10)
$list

And if you really need an array, call the $list.ToArray() method when you're done manipulating the list.

Upvotes: 5

Related Questions