Как проверить, не равно ли каждое свойство объекта в массиве null

#powershell

#powershell

Вопрос:

У меня есть массив объектов, которые я считываю из таблицы SQL Invoke-SqlCmd и которые выглядят следующим образом:

 ARTIKEL_NR          : 74.10095.00
ArtBeschrieb1_3     : Onyx RGB-Strip 14W/m 24V DC Samsung
KLASSE              : LuXLED
SMB1                :
SMW1                :
SMN1                :
SMB2                : Leistung
SMW2                : 14 W/m
SMN2                :
SMB3                : Lichtfarbe
SMW3                : RGB;
 

Но с гораздо большим количеством свойств, около 80.

Теперь я хочу отфильтровать все пустые свойства, не указывая их явно. итак, приведенный выше пример должен быть таким в конце:

 ARTIKEL_NR          : 74.10095.00
ArtBeschrieb1_3     : Onyx RGB-Strip 14W/m 24V DC Samsung
KLASSE              : LuXLED
SMB2                : Leistung
SMW2                : 14 W/m
SMB3                : Lichtfarbe
SMW3                : RGB;
 

Как я могу это сделать?

Я знаю, что могу использовать [string]::IsNullOrEmpty() или [string]::IsNullOrWhiteSpace() , однако я не знаю, как я могу проверить свойства, не перечисляя их явно — под этим я подразумеваю, например:

 Where-Object { ![string]::IsNullOrEmpty($_.SMB1) -and ![string]::IsNullOrEmpty($_.SMW1) -and ...  }
 

.., потому что мои пальцы буквально сломались бы, если бы мне пришлось печатать их все

Ответ №1:

У объектов вызывается psobject набор элементов, который содержит свойства вашего объекта. Вы можете запустить $object.psobject.Properties , чтобы увидеть объекты свойств. Для предоставленного вами объекта вы можете сделать что-то вроде следующего:

 $object | Select ($object.psobject.Properties | Where Value).Name
 

Если у вас есть массив, содержащий объекты, каждый из которых может иметь разные свойства null, вы можете выполнить вышеуказанную фильтрацию для каждого объекта в массиве:

 $array | Foreach-Object {
    $_ | Select ($_.psobject.Properties | Where Value).Name
}
 

Этот параметр имеет оговорку, если первый объект в массиве имеет 4 или менее свойств, тогда отображением по умолчанию будет табличное представление. В табличном представлении будут отображаться только те свойства, которые соответствуют первому объекту. Так что, если $array[0] содержит только SMB3 без нулевого значения, то $array[1] будет отображаться только SMB3 и так далее. Это всего лишь проблема с отображением, поскольку фактические данные точны. Чтобы обойти это, вам нужно будет принудительно просмотреть список:

 $array | Foreach-Object {
    $_ | Select ($_.psobject.Properties | Where Value).Name
} | Format-List
 

Ответ №2:

Попробуйте следующее. С помощью сводного хэш-набора вы можете впоследствии повторно создать унифицированный массив, в противном случае некоторые свойства отсутствуют при использовании командлетов, упомянутых в моем скрипте.

 $inputData = <your-sql-result>

<# 
    summary of all properties required for properly output the data afterwards, 
    when used with cmdlets like Out-GridView, Export-Csv, ConvertTo-Csv, etc
    otherwise some properties are missing, because such cmdlets gets the properties only from first index
#>
$propertySummary = [System.Collections.Generic.HashSet[string]]::new()

$output = foreach ($item in $inputData) {
    $newProperties = [ordered]@{}

    foreach ($property in $item.psobject.properties) {
        if (![string]::IsNullOrEmpty($property.Value)) {
            $newProperties.Add($property.Name, $property.Value)

            # add to summary
            [void]$propertySummary.Add($property.Name)
        }
    }

    [pscustomobject]$newProperties
}

# output with missing properties
$output | Out-GridView -Title 'Missing properties'

# correct output with all properties
$output | Select-Object -Property ([string[]]$propertySummary) | Out-GridView -Title 'Correct'