1

I'm trying to add a Totals line to the array $response_table. The line should be Totals = 56 (number), for example. I've tried $response_table += @{Name="Total"; Count=55};, it adds a line with rubbish data. Can you help with how to add this? Code is below

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
$current_month = (Get-Date).month;
$current_year = (Get-Date).year;

$response_table=@();
$what_year=2019
$month_count=12
$current_month, $total_year, $current_date_interval;
$total_monthly=@(); # empty array, will be populated with values from the API
#$numbers += 5, 2, 3; # to add values to array

if ($what_year -eq $current_year)
{
    $month_count = $current_month-1;
}

for ($current_month=1; $current_month -le $month_count; $current_month++)
{
    $current_date_interval = -join($what_year, "-", $current_month);
    $uri="https://data.police.uk/api/crimes-street/bicycle-theft?poly=53.950624,-1.059234:53.951301,-1.049181:53.947361,-1.043420:53.950333,-1.030671:53.952997,-1.016427:53.950189,-1.013653:53.929487,-1.042286:53.942512,-1.054948:53.941936,-1.057172:53.944481,-1.060155s8&date="+$current_date_interval;
    $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
    $response_table += $response | Group month |Select -Property name,count
    Write-Host $response_table;  
    $response | Group month |Select -Property name,count
    $total_year += $response.count;
}
Write-Host ($response_table|Measure-object -Property count -sum)
$response_table += @{Name="Total"; Count=55};
# does not work
$response_table | export-csv "list.csv" -notypeinformation
#add-content "list.csv" "Total,$total_year"
Write-Host "Yearly total"$total_year;
George
  • 197
  • 2
  • 14
  • 2
    Maybe you should try `$response_table += [pscustomobject]@{Name="Total"; Count=55}` instead. So that you add a custom object with properties you have defined rather than just a hash table. There is likely a better way than all the uses of `+=`. That results in building the entire array every time and is inefficient. – AdminOfThings Nov 22 '19 at 16:15
  • @AdminOfThings The answer to your last point is to use `System.Collections.Generic.List[type]` – codewario Nov 22 '19 at 16:56

1 Answers1

1

As AdminOfThings indicates, you're mistakenly adding a hashtable to the existing array of custom objects (that Select-Object outputs).

To construct a custom object in PSv3+, simply place [pscustomobject] before a hashtable literal, which in your case means:

$response_table += [pscustomobject] @{Name="Total"; Count=55}

Now your Export-Csv command should work as intended.

As an aside: Up to PowerShell 6.x, Export-Csv only (meaningfully) supports custom objects as input, not also hashtables. v7 adds support for hashtables.


Generally avoid using += for appending to arrays:

Arrays are fixed-size data structures, so what PowerShell must do when you "append to" an array with += is to create a new array behind the scenes every time, which is quite inefficient in a loop.

While using an efficiently in-place extensible data structure such as [System.Collections.ArrayList] or [System.Collections.Generic.List[object]] is the next best thing, the simplest and fastest approach is to simply let PowerShell collect multiple output objects in an array ([object[]]) for you, by assigning the entire loop as an expression to a variable:

[array] $response_table = for ($current_month=1; $current_month -le $month_count; $current_month++)
  {
    $current_date_interval = -join($what_year, "-", $current_month);
    $uri="https://data.police.uk/api/crimes-street/bicycle-theft?poly=53.950624,-1.059234:53.951301,-1.049181:53.947361,-1.043420:53.950333,-1.030671:53.952997,-1.016427:53.950189,-1.013653:53.929487,-1.042286:53.942512,-1.054948:53.941936,-1.057172:53.944481,-1.060155s8&date="+$current_date_interval;
    $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers

    # *Output* the result of this pipeline, and PowerShell will
    # collect all outputs for you
    $response | Group month | Select -Property name,count

    $total_year += $response.count;
  }

# It's fine to use += to add the total, because you're only using it *once*.
$response_table += [pscustomobject] @{Name="Total"; Count=55}

Note: The [array] type constraint ensures that $response_table becomes an array even if the loop happens to have just 1 iteration.

mklement0
  • 382,024
  • 64
  • 607
  • 775