J'essaie essentiellement de créer une liste de paires, ce qui s'avère extrêmement difficile
Avant que quiconque mentionne Hashtables, il y aura des doublons dont je ne me soucie pas.
Par exemple, si je fais
$b += @{"dog" = "horse"}
J'obtiens
Name Value ---- ----- dog cat
ce qui est bien. Cependant, je ne parviens pas à ajouter des éléments similaires à
$b = @{"dog" = "cat"}
L'élément a déjà été ajouté. Clé dans le dictionnaire: 'dog' Clé ajoutée: 'dog'
J'essaie simplement de créer un tableau de données auquel je peux ajouter en utilisant quelque chose comme .Add ()
ou + =
.
4 Réponses :
Je pense qu'une liste de tables de hachage devrait accomplir ce que vous recherchez.
$ht = @{foo='bar'} $list = [System.Collections.Generic.List[hashtable]]::new() $list.Add($ht) $list.Add($ht) $list.Add($ht) $list
Merci, mais j'obtiens l'erreur ci-dessous en essayant de définir l'invocation de la méthode $ list a échoué car [System.Collections.Generic.List1 [[System.Collections.Hashta ble, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089]]] ne contient pas de méthode nommée 'new'. À la ligne: 1 char: 1 + $ results = [System.Collections.Generic.List [hashtable]] :: new () + ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ ~~ + CategoryInfo: InvalidOperation: (: ) [], RuntimeException + FullyQualifiedErrorId: MethodNotFound
Vous êtes alors sur une ancienne version de PowerShell. Vous devrez utiliser $ list = New-Object -TypeName 'System.Collections.Generic.List [hashtable]'
La réponse utile de Persistent13 offre une solution efficace et efficiente - quoique légèrement obscure.
Créer un tableau de tables de hachage est la solution la plus simple, mais il est important de noter que "étendre" un tableau signifie implicitement le recréer , étant donné que les tableaux sont des structures de données de taille fixe, qui peuvent devenir un problème de performances avec de nombreuses itérations:
# Using array-construction operator ",", create a single-element array # containing a hashtable $b = , @{ dog = "cat"} # "Extend" array $b by appending another hashtable. # Technically, a new array must be allocated that contains the original array's # elements plus the newly added one. $b += @{ dog = "horse"}
Ceci Le problème GitHub traite d'une éventuelle amélioration future pour que PowerShell prenne en charge nativement un type de données de type liste extensible de manière efficace ou pour qu'il soit par défaut à un tel type de données. (À partir de Windows PowerShell v5.1 / PowerShell Core 6.2.0, PowerShell utilise par défaut des tableaux de taille fixe, de type [object[ Oft[.... )
).
Si vous voulez une liste de tuples, je vous recommande de créer une liste de tuples :
function New-Tuple { Param( [Parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [ValidateCount(2,20)] [array]$Values ) Process { $types = ($Values | ForEach-Object { $_.GetType().Name }) -join ',' New-Object "Tuple[$types]" $Values } } $tuples = ('dog', 'cat'), ('dog', 'horse') | New-Tuple
Notez que dans cet exemple $ list
est un tableau régulier, ce qui signifie que , comme l'a souligné @ mklement0 dans sa réponse, en y ajoutant l'opérateur d'affectation + =
recrée le tableau avec une taille augmentée de 1, place le nouvel élément dans le nouvel emplacement vide, puis remplace le tableau d'origine. Pour un petit nombre d'opérations d'ajout, ce n'est généralement pas un gros problème, mais avec un nombre croissant d'opérations d'ajout, l'impact sur les performances devient significatif.
Utiliser un ArrayList
au lieu d'un simple array évite ce problème:
function New-Tuple { Param( [Parameter(Mandatory=$true)] [ValidateCount(2,2)] [string[]]$Values ) New-Object 'Tuple[String,String]' $Values } $tuple1 = New-Tuple 'dog', 'cat' $tuple2 = New-Tuple 'dog', 'horse'
La méthode Add ()
des objets ArrayList
renvoie l'index où l'élément a été ajouté . Out-Null
supprime cette sortie qui est dans la plupart des cas indésirable. Si vous souhaitez travailler avec ces numéros d'index, vous pouvez les collecter dans une variable au lieu de les supprimer ( $ i = $ list.Add ($ t1)
).
Si vous voulez éviter d'avoir à spécifier le type d'un nouveau tuple tout le temps, vous pouvez l'envelopper dans une fonction réutilisable comme celle-ci:
$list = New-Object Collections.ArrayList $tuple1 = New-Object 'Tuple[String,String]' 'dog', 'cat' $tuple2 = New-Object 'Tuple[String,String]' 'dog', 'horse' $list.Add($tuple1) | Out-Null $list # Output: # # Item1 Item2 Length # ----- ----- ------ # dog cat 2 $list.Add($tuple2) | Out-Null $list # Output: # # Item1 Item2 Length # ----- ----- ------ # dog cat 2 # dog horse 2
ou, d'une manière plus générique, comme ceci:
$list = @() $tuple1 = New-Object 'Tuple[String,String]' 'dog', 'cat' $tuple2 = New-Object 'Tuple[String,String]' 'dog', 'horse' $list += $tuple1 $list # Output: # # Item1 Item2 Length # ----- ----- ------ # dog cat 2 $list += $tuple2 $list # Output: # # Item1 Item2 Length # ----- ----- ------ # dog cat 2 # dog horse 2
Merci à mklement0 comme ci-dessous est probablement la solution la plus simple
$ht = @{foo='bar'} $list = [System.Collections.Generic.List[hashtable]]::new() $list.Add($ht) $list.Add($ht) $list.Add($ht) $list
Et la méthode de Persistent13 donne également un itinéraire facile
$b = , @{ dog = "cat"} $b += @{ dog = "horse"}
Je suppose que je était juste surpris qu'il n'y ait pas de moyen plus enraciné d'obtenir ce que je pense être un type d'objet assez basique / standard