arrayspowershellslice

Slice of Strings Operation Reports System.Object Array Conversion Error


When attempting to replace values in a slice of a string array I am getting this error

Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32".

on code such as

$al[1..3] = $al[1..3] -replace '^', '//'

or

$al[1..3] = $al[1..3] | ForEach-Object { "//" + $_ }

How can I use an array slice to modify strings within the array?


Here is a non slice example which does not generate an error

$al = @('Zero', 'One', 'Two', 'Three', 'Four')
$al[1] = "//" + $al[1];
$al[2] = "//" + $al[2];
$al[3] = "//" + $al[3];

Write-Host $al  # Outputs: Zero //One //Two //Three Four

tldr: How does one add text to the beginning of specific slice of lines in a powershell string array?


Solution

  • PowerShell doesn't support assigning values to array slices such as $al[1..3]; also, such an expression isn't a slice in the sense that it is a window into an existing array; rather, it is a new array comprising the requested elements.

    (Unfortunately, the wording of the error message when you attempt such an assignment is confusing; this has been reported in GitHub issue #23980)

    To modify the array in-place in a concise manner, I suggest using a switch statement:

    $al = @('Zero', 'One', 'Two', 'Three', 'Four')
    
    switch (1..3) {
      default { $al[$_] = '//' + $al[$_] }
    }
    

    Another option is to compose a new array by concatenating the unmodified elements with those modified via -replace:

    $al = @('Zero', 'One', 'Two', 'Three', 'Four')
    
    $newAl =
      @($al[0]) + ($al[1..3] -replace '^', '//') + $al[4]
    

    Note the need to enclose the first operand of the + operation in @(...) so as to ensure that + performs array concatenation.

    Also note that the indices of the unmodified elements are of necessity hard-coded, because other than [-1] to refer to the last element - PowerShell's index expressions do not support implied range endpoints.

    GitHub issue #7940 is a long-standing proposal to bring this functionality, which C# has had for a while, to PowerShell. If this were implemented, the concept of "the 5th element plus any thereafter" could be expressed as $al[4..]