Конвейерная передача пустого объекта имеет счетчик 1

Кажется, я не могу правильно понять эту функцию. Я хочу передать ему объект, и если объект пуст, вернуть 1, иначе подсчитать элементы в объекте и увеличить на 1.

Предполагая следующую функцию "New-Test":

function New-Test
{
    [cmdletbinding()]
    Param
    (
        [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
        [object[]]$Object
        #[object]$object
    )
    Begin
    {
        $oData=@()    
    }
    Process
    {
        "Total objects: $($object.count)"
        if($Object.count -gt 0)
        {
            $oData += [pscustomobject]@{
                Name = $_.Name
                Value = $_.Value
            }    
        }
        Else
        {
            Write-Verbose "No existing object to increment. Assuming first entry."
            $oData = [pscustomobject]@{Value = 0}
        }
    }
    End
    {
        $LatestName = ($oData | Sort-Object -Descending -Property Value | Select -First 1).value
        [int]$intNum = [convert]::ToInt32($LatestName, 10)
        $NextNumber = "{0:00}" -f ($intNum+1)
        $NextNumber
    }
}

И следующая тестовая хеш-таблица:

#Create test hashtable:
$a = 00..08
$obj = @()
$a | foreach-object{
    $obj +=[pscustomobject]@{
        Name = "TestSting" + "{0:00}" -f $_
        Value = "{0:00}" -f $_
    }
} 

Согласно приведенной выше функции, если я передам ей $Obj, я получу:

$obj | New-Test -Verbose
Total objects: 1
Total objects: 1
Total objects: 1
Total objects: 1
Total objects: 1
Total objects: 1
Total objects: 1
Total objects: 1
Total objects: 1
09

Что, как и ожидалось. Однако, если я передам его $Obj2:

#Create empty hash
$obj2 = $null
$obj2 = @{}

$obj2 | New-Test -Verbose

Я получил:

Total objects: 1
Exception calling "ToInt32" with "2" argument(s): "Index was out of range.     Must be non-negative and less than the size of the collection.
Parameter name: startIndex"
At line:33 char:9
+         [int]$intNum = [convert]::ToInt32($LatestName, 10)
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

01

Я не понимаю, почему $object.count равен 1, когда в хеш-таблице ничего нет.

Если я изменю параметр, тип $object с [object[]] на [object], результат проверки пустой хэш-таблицы:

$obj2 | New-Test -Verbose
Total objects: 0
VERBOSE: No existing object to increment. Assuming first entry.
01

Однако именно этого я и ожидал, если я запущу первый тест, это приведет к:

$obj | New-Test -Verbose
Total objects: 
VERBOSE: No existing object to increment. Assuming first entry.
Total objects: 
VERBOSE: No existing object to increment. Assuming first entry.

На этот раз в $objects ничего нет.

Я уверен, что это просто, но я не могу понять это. Любая помощь приветствуется.

P.S. PowerShell 5.1


person woter324    schedule 26.01.2017    source источник
comment
Я заметил, что вы назначаете хеш-таблицу $obj2, а не массив, которым инициализируется $obj1.   -  person campbell.rw    schedule 26.01.2017
comment
вы всегда можете использовать measure-object, чтобы увидеть количество непосредственно для функции. Вы работаете напрямую, получая счет как 2, если запускаете New-Test | Measure-Object.   -  person Ranadip Dutta    schedule 26.01.2017


Ответы (1)


$obj2 — это хеш-таблица, а не массив. Хеш-таблицы по умолчанию не нумеруются, поэтому сама хеш-таблица является одним объектом. Если вы хотите перебрать хеш-таблицу с помощью конвейера, вам нужно использовать $obj2.GetEnumerator().

@{"hello"="world";"foo"="bar"} | Measure-Object | Select-Object Count

Count
-----
    1

@{"hello"="world";"foo"="bar"}.GetEnumerator() | Measure-Object | Select-Object Count

Count
-----
    2
person Frode F.    schedule 26.01.2017