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;
2
  • 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. Commented Nov 22, 2019 at 16:15
  • @AdminOfThings The answer to your last point is to use System.Collections.Generic.List[type] Commented Nov 22, 2019 at 16:56

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.