2011-05-14 20 views
18

tengo:¿Cómo se suman varios elementos en un objeto en PowerShell?

$report.gettype().name 
Object[] 

echo $report 

Item      Average 
--       ------- 
orange      0.294117647058824 
orange     -0.901960784313726 
orange     -0.901960784313726 
grape      9.91335740072202 
grape      0 
pear      3.48736462093863 
pear      -0.0324909747292419 
pear      -0.0324909747292419 
apple      12.1261261261261 
apple      -0.0045045045045045 

Quiero crear una variable, $ total (como una tabla hash) que contiene la suma de la columna 'Media' para cada elemento, por ejemplo,

echo $total 

orange -1.5097 
grape 9.913 
pear  3.423 
apple 12.116 

en este momento estoy pensando en un bucle a través del informe $, pero es demonios feos, y estoy buscando algo más elegante que el siguiente punto de partida (incompleta):

$tmpPrev = "" 
foreach($r in $report){ 
    $tmp = $r.item 
    $subtotal = 0 
    if($tmp <> $tmpPrev){ 
     $subtotal += $r.average 
    } 

¿Cómo podría hacer esto?

Respuesta

5

No sé si puede deshacerse de los bucles. ¿Qué hay de:

$report | % {$averages = @{}} { 
    if ($averages[$_.item]) { 
     $averages[$_.item] += $_.average 
    } 
    else { 
     $averages[$_.item] = $_.average 
    } 
} {$averages} 
+0

gracias empo ... ¡Estoy consiguiendo: El operador splatting '@' no puede ser utilizado para hacer referencia a variables en un expressi sucesivamente. '@averages' se puede usar solo como argumento para un comando. Para hacer referencia a vari ables en una expresión, use '$ promedios'. .... ¿es un problema de mi parte o un problema con el código? – ted

+0

@ted: Lo siento. Ese fue un código erróneo, ahora corregido. Todavía tengo poco sueño ;-) –

+0

gracias empo, funciona ahora. – ted

40

cmdlets Group-Object y Measure-Object ayuda para resolver la tarea en un PowerShell-ish manera:

Código:

# Demo input 
$report = @(
    New-Object psobject -Property @{ Item = 'orange'; Average = 1 } 
    New-Object psobject -Property @{ Item = 'orange'; Average = 2 } 
    New-Object psobject -Property @{ Item = 'grape'; Average = 3 } 
    New-Object psobject -Property @{ Item = 'grape'; Average = 4 } 
) 

# Process: group by 'Item' then sum 'Average' for each group 
# and create output objects on the fly 
$report | Group-Object Item | %{ 
    New-Object psobject -Property @{ 
     Item = $_.Name 
     Sum = ($_.Group | Measure-Object Average -Sum).Sum 
    } 
} 

Salida:

Sum Item 
--- ---- 
    3 orange 
    7 grape 
7

I' Tengo una solución más de línea de comandos.

$ Dada informe

$groupreport = $report | Group-Object -Property item -AsHashTable 

es

Name  Value 
----  ----- 
grape {@{Item=grape; Average=9.91335740072202}, @{Item=grape; Average=0}} 
orange {@{Item=orange; Average=0.294117647058824}, @{Item=orange; Average=-0.901960784313726... 
apple {@{Item=apple; Average=12.1261261261261}, @{Item=apple; Average=-0.0045045045045045}} 
pear  {@{Item=pear; Average=3.48736462093863}, @{Item=pear; Average=-0.0324909747292419}, @... 

continuación

[email protected]{} 
$groupreport.keys | % {$tab += @{$_ = ($groupreport[$_] | measure-object -Property average -sum)}} 

da

PS> $tab["grape"] 

Count : 2 
Average : 
Sum  : 9,91335740072202 
Maximum : 
Minimum : 
Property : Average 

PS> $tab["grape"].sum 
9,91335740072202 

Parece corto y utilizable.

Resumen

$groupreport = $report | Group-Object -Property item -AsHashTable 
$tab = @{} 
$groupreport.keys | % {$tab += @{$_ = ($groupreport[$_] | measure-object -Property average -sum)}} 
$tab.keys | % {write-host $_ `t $tab[$_].sum} 
Cuestiones relacionadas