SimonS
SimonS

Reputation: 1973

How to check if each property of an object in an array is not null

I have an Array of Objects that I read out from an SQL table with Invoke-SqlCmd that look like this:

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;

But with a lot more properties, around 80.

Now I want to filter out all empty properties, without stating them explicitly. so the example above should be this in the end:

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;

How can I do that?

I know I can use [string]::IsNullOrEmpty() or [string]::IsNullOrWhiteSpace(), however I don't know how I can check the properties without listing them explicitly - by that I mean e.g:

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

... because my fingers would literally break if I would have to type them all

Upvotes: 1

Views: 1324

Answers (2)

swbbl
swbbl

Reputation: 864

Try the following. With the summary hashset you are able to re-create a uniformed array afterwards, otherwise some properties are missing, when using cmdlets mentioned in my script.

$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'

Upvotes: 0

AdminOfThings
AdminOfThings

Reputation: 25001

Objects have a MemberSet called psobject that contains the properties of your object. You can run $object.psobject.Properties to see the property objects. For the object you have provided, you can do something like the following:

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

If you have an array containing objects that each may have different null properties, you can perform the above filtering per object in the array:

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

This option has a caveat if the first object in the array has 4 or less properties, then the default display will be table view. Table view will only display the properties that correspond to the first object. So if $array[0] only contains SMB3 without a null value, then $array[1] will only display SMB3 and so on. This is only a display issue as the actual data is accurate. To get around this, you will need to force a the list view:

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

Upvotes: 3

Related Questions