How to get a single property value from an array of objects?

14,541

Solution 1

another option

($list |?{ $_.guid -eq '0EDC361C-862E-41FC-8A60-870CADC17EC5'}).title

Solution 2

Making a hash of hash is probably the most efficient and most elegant solution if you can slighltly change your data structure:

$hashtable = @{}

$hashtable.Add('0118B390-3AF5-406E-920D-FE140392584D', @{title='First';guid='0118B390-3AF5-406E-920D-FE140392584D'})
$hashtable.Add('2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188', @{title='Second';guid='2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188'})
$hashtable.Add('0EDC361C-862E-41FC-8A60-870CADC17EC5', @{title='Third';guid='0EDC361C-862E-41FC-8A60-870CADC17EC5'})

You can then retrieve your title from the guid this way:

$hashtable['2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188'].title

Solution 3

If you want just the value of a single property, the simplest way is to define $list as an array of custom objects and expand that property:

$list = @(
  [pscustomobject]@{title='First';guid='0118B390-3AF5-406E-920D-FE140392584D'},
  [pscustomobject]@{title='Second';guid='2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188'},
  [pscustomobject]@{title='Third';guid='0EDC361C-862E-41FC-8A60-870CADC17EC5'}
)

$list | where guid -eq '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188' | select -Expand title

That requires PowerShell v3 or newer, though. If you're stuck with PowerShell v2 or earlier, or can't cast the hashtables to custom objects for one reason or the other, you could echo the title property in a loop (similar to what @hysh_00 suggested):

$list | where guid -eq '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188' | % { $_.title }

Solution 4

This is another way to access the Value.

PS:> $list = @( `
>>                 @{title='First';guid='0118B390-3AF5-406E-920D-FE140392584D'}, `
>>                 @{title='Second';guid='2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188'}, `
>>                 @{title='Third';guid='0EDC361C-862E-41FC-8A60-870CADC17EC5'} `
>>             )
>>
PS:> $list|%{if($_.ContainsValue('0EDC361C-862E-41FC-8A60-870CADC17EC5')){$_.title}}
Third
PS:>
Share:
14,541
Simon Tewsi
Author by

Simon Tewsi

I moved into IT after several years as an electronic engineer. Starting out at the bottom I worked my way up through VBA macros to Access then T-SQL (SQL Server) development. Since 2005 I've been doing middleware and backend development in C# and T-SQL. On the side I'm enjoying working with PowerShell, FitNesse and Azure DevOps. I'm also getting into Docker, Kubernetes and Azure. #SOreadytohelp

Updated on June 14, 2022

Comments

  • Simon Tewsi
    Simon Tewsi almost 2 years

    I've an array of objects:

    $list = @( `
                    @{title='First';guid='0118B390-3AF5-406E-920D-FE140392584D'}, `
                    @{title='Second';guid='2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188'}, `
                    @{title='Third';guid='0EDC361C-862E-41FC-8A60-870CADC17EC5'} `
                )
    

    I want to use the guid to look up and return a title. All I want is the value, I don't want to return an object. For example, if looking up guid '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188' I just want to return a string value 'Second', rather than an object with a property whose value is 'Second'.

    How can I do this?

    I've tried the following:

    $list | where guid -eq '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188'
    

    which returns a hash table

    and

    $list | where guid -eq '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188' | select {$_.title}
    

    which returns a PSObject with a {$_.title} NoteProperty.

    The following two attempts work:

    ($list | where guid -eq '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188' `
        | select {$_.title}).{$_.title}
    
    ($list | where guid -eq '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188' `
        | select @{Name="result";Expression={$_.title}}).result
    

    However, they're both ugly. Is there a better way of returning just the value?

  • Simon Tewsi
    Simon Tewsi about 9 years
    This looks very attractive, just the sort of thing I was after, but I get an error when I try it: select : Property "title" cannot be found. ... FullyQualifiedErrorId : ExpandPropertyNotFound,Microsoft.PowerShell.Commands.SelectO‌​bjectCommand. This is with PowerShell 4.0. Is there some configuration setting I need, or some other setting required to get it to work?
  • Ansgar Wiechers
    Ansgar Wiechers about 9 years
    @SimonTewsi Sorry, I missed that you have a list of hashtables, not objects. See updated answer.
  • Simon Tewsi
    Simon Tewsi about 9 years
    While all answers have their merits, I'm choosing this one as it seems to me the most flexible. My actual scenario is a bit more complicated than the simplified details in the question: The real hash tables have multiple elements and I want to be able to look up different elements using either the title or the GUID. I can use this method to look up any element using any other element (as long as the lookup element is unique).
  • Simon Tewsi
    Simon Tewsi about 9 years
    A very clean solution but not as flexible as the answer from Kayasax. For straight-forward situations, this would be the way I would go.
  • Simon Tewsi
    Simon Tewsi about 9 years
    BTW, for others, the hash table can be built a little more simply: $hashtable = @{'0118B390-3AF5-406E-920D-FE140392584D'=@{title='First'}; '2C78DA61-B6EF-4E4E-8FF8-4A95D75C8188'=@{title='Second'};...‌​etc...} It may be overkill for just a title element but I actually have other elements I want to add to each child hash table. It works just as well with multiple elements in each child hash table.