rule request: AvoidPlusEqualToPopulateDictionary
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 45/100
調査の方向性
この issue では実装ファイルもテストも指定されていません。まず += に対する既存のルールとそのテストパターンを探し、次に、動的なキーを持つ単一エントリのハッシュテーブルが += に続く場合を、ルールがどのように区別するかを確認してください。新しいルールが対象となる辞書追加の形式を報告し、ドキュメント化されている角括弧、ドット、Add の代替手段を維持できれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Avoid assignment by addition operator (+=) to populate a dictionary
As with using the assignment by addition operator (+=) to build a collection or a string, populating a dictionary using the assignment by addition operator (+=) is in effective:
Tests
$tests = @{
'Array+=' = {
param($count)
$result = @()
foreach($i in 1..$count) {
$result += $i
}
}
'IList.Add' = {
param($count)
$result = [Collections.Generic.List[int]]::new()
foreach($i in 1..$count) {
$result.Add($i)
}
}
'IList+=' = {
param($count)
$result = [Collections.Generic.List[int]]::new()
foreach($i in 1..$count) {
$result += $i
}
}
'IDictionary[]' = {
param($count)
$result = @{}
foreach($i in 1..$count) {
$result[$i] = $i
}
}
'IDictionary.Add' = {
param($count)
$result = @{}
foreach($i in 1..$count) {
$result.Add($i, $i)
}
}
'IDictionary+=' = {
param($count)
$result = @{}
foreach($i in 1..$count) {
$result += @{ $i = $i }
}
}
} # Tests
1kb, 5kb, 10kb | ForEach-Object {
$groupResult = foreach($test in $tests.GetEnumerator()) {
$ms = (Measure-Command { & $test.Value -Count $_ }).TotalMilliseconds
[pscustomobject]@{
CollectionSize = $_
Test = $test.Key
TotalMilliseconds = [Math]::Round($ms, 2)
}
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
}
$groupResult = $groupResult | Sort-Object TotalMilliseconds
$groupResult | Select-Object *, @{
Name = 'RelativeSpeed'
Expression = {
$relativeSpeed = $_.TotalMilliseconds / $groupResult[0].TotalMilliseconds
$speed = [Math]::Round($relativeSpeed, 2).ToString() + 'x'
if ($speed -eq '1x') { $speed } else { $speed + ' slower' }
}
} | Format-Table -AutoSize
}
CollectionSize Test TotalMilliseconds RelativeSpeed
-------------- ---- ----------------- -------------
1024 IDictionary[] 0.19 1x
1024 IList.Add 0.35 1.84x slower
1024 IDictionary.Add 0.50 2.63x slower
1024 Array+= 0.74 3.89x slower
1024 IList+= 1.16 6.11x slower
1024 IDictionary+= 39.17 206.16x slower
CollectionSize Test TotalMilliseconds RelativeSpeed
-------------- ---- ----------------- -------------
5120 IDictionary[] 0.71 1x
5120 IDictionary.Add 1.41 1.99x slower
5120 IList.Add 1.50 2.11x slower
5120 IList+= 20.33 28.63x slower
5120 Array+= 21.51 30.3x slower
5120 IDictionary+= 1880.89 2649.14x slower
CollectionSize Test TotalMilliseconds RelativeSpeed
-------------- ---- ----------------- -------------
10240 IDictionary[] 0.92 1x
10240 IDictionary.Add 3.79 4.12x slower
10240 IList.Add 4.71 5.12x slower
10240 IList+= 71.91 78.16x slower
10240 Array+= 86.93 94.49x slower
10240 IDictionary+= 5502.40 5980.87x slower
Instead use (even for a single item):
- the square bracket syntax (
$Dictionary[$Key] = $Value) or dot syntax ($Dictionary.$Key = $Value) which will overwrite any duplicate key - the
.Add()method ($Dictionary($Key, $Value)) which returns an error when the key already exists
Proposed technical implementation details (optional)
As apposed to the requests for avoiding the assignment by addition operator (+=) to build a collection or a string, the majority of this bad practice syntax would be easier to capture:
- Check for the
+=operator - Directly followed by a hash table syntax
@{ ... }- With a single key-value pair
- And a dynamic key
Even using a simple search string will capture lot of issues (note that almost all results are embedded in a foreach loop):
https://github.com/search?q=language%3Apowershell+%22%2b=%20@%7B%20$%22&type=code
The LHS could still be anything else than a presumed IDictionary, e.g. an IList.
But than there is still a good reason to avoid the += operator...
What is the latest version of PSScriptAnalyzer at the point of writing
1.24.0
- 主要言語
- C#
- スター
- 2.2k
- フォーク
- 415
- 平均マージ
- 13時間 1分
- マージ済み PR(30日)
- 2
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
PowerShell/PSScriptAnalyzer のほかの issue
-
Up-for-Grabs
難易度 1/5 1〜3時間 初心者へのやさしさ 78/100
PowerShell/PSScriptAnalyzer#2213 · コメント 2 件 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
PowerShell/PSScriptAnalyzer#2217 · コメント 1 件 ·
-
PSUseConsistentIndentation double-indents attribute bodies that open a scriptblock (`[Attr({ … })]`) オープン
難易度 3/5 1〜2日 初心者へのやさしさ 70/100
PowerShell/PSScriptAnalyzer#2216 · コメント 2 件 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
PowerShell/PSScriptAnalyzer#2211 ·
-
`PSPlaceOpenBrace` and `PSPlaceCloseBrace` leave trailing whitespace when expanding one-line blocks オープン
難易度 3/5 1〜2日 初心者へのやさしさ 70/100
PowerShell/PSScriptAnalyzer#2210 ·
PowerShell/PSScriptAnalyzer の issue をすべて見る
似ている issue
-
:watch: Not Triaged dotnet-fsharp/svc
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
-
Client customer-reported needs-team-attention question Service Attention WebPubSub
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
Azure/azure-sdk-for-net#63292 · コメント 3 件 · リアクション 1 件 ·
-
Issue-Enhancement Needs-Triage
難易度 1/5 1時間未満 初心者へのやさしさ 86/100
PowerShell/PowerShell#28061 · リアクション 2 件 ·
-
dependencies needs-team-triage server-Azure.Mcp
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
aspnet-core/svc aspnetcore-signalr/subsvc doc-enhancement Pri2 SignalR
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
dotnet/AspNetCore.Docs#37729 ·