rule request: AvoidPlusEqualToPopulateDictionary
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 45/100
Piste de recherche
L’issue ne nomme aucun fichier d’implémentation ni aucun test. Commencez par localiser les règles existantes pour += et leurs modèles de test, puis vérifiez comment une règle distinguerait += suivi d’une table de hachage à entrée unique avec une clé dynamique. Le travail est terminé lorsque la nouvelle règle signale la forme ciblée de remplissage du dictionnaire tout en conservant les alternatives documentées avec crochets, point et Add.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
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
- Langage dominant
- C#
- Étoiles
- 2.2k
- Forks
- 415
- Merge moyen
- 13 h 1 min
- PR mergées (30 j)
- 2
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de PowerShell/PSScriptAnalyzer
-
Up-for-Grabs
Difficulté 1/5 1-3 heures Accessibilité débutants 78/100
PowerShell/PSScriptAnalyzer#2213 · 2 commentaires ·
-
Difficulté 3/5 1-2 jours Accessibilité débutants 72/100
PowerShell/PSScriptAnalyzer#2217 · 1 commentaire ·
-
PSUseConsistentIndentation double-indents attribute bodies that open a scriptblock (`[Attr({ … })]`) Ouverte
Difficulté 3/5 1-2 jours Accessibilité débutants 70/100
PowerShell/PSScriptAnalyzer#2216 · 2 commentaires ·
-
Difficulté 3/5 1-2 jours Accessibilité débutants 68/100
PowerShell/PSScriptAnalyzer#2211 ·
-
`PSPlaceOpenBrace` and `PSPlaceCloseBrace` leave trailing whitespace when expanding one-line blocks Ouverte
Difficulté 3/5 1-2 jours Accessibilité débutants 70/100
PowerShell/PSScriptAnalyzer#2210 ·
Toutes les issues de PowerShell/PSScriptAnalyzer
Issues similaires
-
release-notes in .NET 11 RC2 Ouvertepriority-0
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 78/100
StackExchange/StackExchange.Redis#3249 ·
-
[Feat] 조합 영역 구분선 개선 Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
-
type/automation type/tech-debt
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 88/100