How to exclude non-valued object properties when c

2019-02-13 02:03发布

问题:

I have a piece of code that works but I want to know if there is a better way to do it. I could not find anything related so far. Here are the facts:

  • I have an object with n properties.
  • I want to convert this object to JSON using (ConvertTo-Json).
  • I don't want to include in the JSON those object properties that are not valued.

Building the object (not really important):

$object = New-Object PSObject
Add-Member -InputObject $object -MemberType NoteProperty -Name TableName -Value "MyTable"
Add-Member -InputObject $object -MemberType NoteProperty -Name Description -Value "Lorem ipsum dolor.."
Add-Member -InputObject $object -MemberType NoteProperty -Name AppArea -Value "UserMgmt"
Add-Member -InputObject $object -MemberType NoteProperty -Name InitialVersionCode -Value ""

The line that I need improvements (to filter out the non-valued properties and not include them in the JSON)

# So I want to 'keep' and deliver to the JSON only the properties that are valued (first 3).
$object | select -Property TableName, Description, AppArea, InitialVersion | ConvertTo-Json

What this line delivers:

Results:
{
    "TableName":  "MyTable",
    "Description":  "Lorem ipsum dolor..",
    "AppArea":  "UserMgmt",
    "InitialVersion":  null
}

What I want to obtain:
{
    "TableName":  "MyTable",
    "Description":  "Lorem ipsum dolor..",
    "AppArea":  "UserMgmt"
}

What I've tried and works, but I don't like it since I have much more properties to handle:

$JSON = New-Object PSObject

if ($object.TableName){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name TableName -Value $object.TableName
}

if ($object.Description){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name Description -Value $object.Description
}

if ($object.AppArea){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name AppArea -Value $object.AppArea
}

if ($object.InitialVersionCode){
   Add-Member -InputObject $JSON -MemberType NoteProperty -Name InitialVersionCode -Value $object.InitialVersionCode
}

$JSON | ConvertTo-Json

回答1:

Something like this?

$object = New-Object PSObject

Add-Member -InputObject $object -MemberType NoteProperty -Name TableName -Value "MyTable"
Add-Member -InputObject $object -MemberType NoteProperty -Name Description -Value "Lorem ipsum dolor.."
Add-Member -InputObject $object -MemberType NoteProperty -Name AppArea -Value "UserMgmt"
Add-Member -InputObject $object -MemberType NoteProperty -Name InitialVersionCode -Value ""

# Iterate over objects
$object | ForEach-Object {
    # Get array of names of object properties that can be cast to boolean TRUE
    # PSObject.Properties - https://msdn.microsoft.com/en-us/library/system.management.automation.psobject.properties.aspx
    $NonEmptyProperties = $_.psobject.Properties | Where-Object {$_.Value} | Select-Object -ExpandProperty Name

    # Convert object to JSON with only non-empty properties
    $_ | Select-Object -Property $NonEmptyProperties | ConvertTo-Json
}

Result:

{
    "TableName":  "MyTable",
    "Description":  "Lorem ipsum dolor..",
    "AppArea":  "UserMgmt"
}


回答2:

beatcracker's helpful answer offers an effective solution; let me complement it with a streamlined version that takes advantage of PSv4+ features:

# Sample input object
$object = [pscustomobject] @{
  TableName = 'MyTable'
  Description = 'Lorem ipsum dolor...'
  AppArea = 'UserMgmt'
  InitialVersionCode = $null
}

# Start with the list of candidate properties.
# For simplicity we target *all* properties of input object $obj
# but you could start with an explicit list as wellL
#   $candidateProps = 'TableName', 'Description', 'AppArea', 'InitialVersionCode'
$candidateProps = $object.psobject.properties.Name

# Create the filtered list of those properties whose value is non-$null
# The .Where() method is a PSv4+ feature.
$nonNullProps = $candidateProps.Where({ $null -ne $object.$_ })

# Extract the list of non-null properties directly from the input object
# and convert to JSON.
$object | Select-Object $nonNullProps | ConvertTo-Json