Home > other >  Remove column of array of object
Remove column of array of object

Time:08-06

I have an array with psocustomobjet like this :

$Data=@()
$Data  = [PSCustomObject]@{
'RawMessage' = '123'
'MessageType' = 'String'
'Export' = ''}
$Data  = [PSCustomObject]@{
'RawMessage' = '456'
'MessageType' = 'File'
'Export' = ''}
$Data  = [PSCustomObject]@{
'RawMessage' = '789'
'MessageType' = 'String'
'Export' = ''}

If column "export" is empty, I would like to remove it to get the following result :

RawMessage MessageType
---------- -----------
123        String
456        File
789        String

My control seem good but I didn't manage to remove the column :

If ($Data.Export -NotLike $Null) {$Data.PSObject.Properties.Remove('Export')}

I tried a lot of commands but I keep with my column...

Thank for your help.

CodePudding user response:

Please accept mklement0's answer, as it gives you a good solution to accomplish what you asked for, and explains what was wrong with what you tried. I am only including this as a different way to iterate the array looking for empty values.

Since we can use If to evaluate $true if there is there is a non-zero/non-false value, and we can invert those results, we can pipe your array to Select-Object and for the ExcludeProperty parameter supply a subexpression that looks to see if anything has a value for "Export", and if nothing does then exclude that property.

$Data | Select * -ExcludeProperty $(if(!($Data.Export -ne '')){'Export'}) | Format-Table -AutoSize

This works because $Data.Export -ne '' outputs the Export value of any object in the array that is not equal to ''. If nothing has a non-'' value then nothing is output and it evaluates as $null, and If equates $null with $false, so we precede it is ! (alias for -not), and tell it that if not false, to output 'Export' to the -ExcludeProperty parameter. Reading this answer makes it all seem very convoluted, but it works. Run it, then change the value of Export on any of the objects and try it again. It outputs like you want either way.

Or if you wanted to remove the property and not just output it you could lose the Format-Table and capture the output in itself like this:

$Data = $Data|Select * -ExcludeProperty $(if(!($Data.Export -ne '')){'Export'})

CodePudding user response:

Since you want to remove the Export property from individual objects objects where that value is '' (the empty string), you must process them individually:

$Data | ForEach-Object {
  if ('' -eq $_.Export)  { $_.PSObject.Properties.Remove('Export') }
  $_ # Output
}
  • The ForEach-Object cmdlet is one way to (in effect) loop (iterate) over the individual objects contained in your $Data array, with each element reflected in the automatic $_ variable. Alternatively, especially for arrays already in memory, you may use the foreach statement.

  • Note that it is generally sufficient to test [string] values for '' (the empty string) in PowerShell, not also for $null, because PowerShell doesn't store $null in string values (see this answer for more information).

    • However, if you don't know the type of the property ahead of time and want to test for $null too, you can use the [string]::IsNullOrEmpty($_.Export) - or, more simply - $_.Export -like ''

As for what you tried:

$Data is an array of objects, and you mistakenly tried to remove the property from the array object rather than from the objects that make up its elements.

$Data.Export, due to PowerShell's member-access enumeration feature, does act on the individual elements, but returns their .Export property values as an array.

As such, you can use the following tests at the array level, but in order to modify the elements, you need to enumerate (iterate over) them and process each.

# Is at least *one* .Export value the empty string?
$Data.Export -contains ''

# Are *all* .Export values the empty string?
($Data.Export -eq '').Count -eq $Data.Count
  • Related