none
Find value in array RRS feed

  • Question

  • I know that one value in an array will be the string STATUS.  How would I search the array for this value and then get the value of the item that is 2 spots past it.

    Here is a hypothetical array....

    Status

    Here

    Is

    A

    Hypothetical

    Array

    I understand that array[1] would give me the value STATUS and array[3] would give me the value IS but my problem is that I won't always know the exact location of the value STATUS.  All I know is that it will always be one of the values.

     

    Sunday, January 29, 2012 3:01 AM

Answers

  • I got the value in a round about way by finding the index, incrementing it by 2, and getting the value of the array at that index. 

     

    $status = 0..($items.Count - 1) | Where { $items[$_] -eq $status }

    $valueline = $status + 2

    $items[$valueline]

    • Marked as answer by Carlos052010 Sunday, January 29, 2012 3:41 AM
    • Unmarked as answer by Carlos052010 Sunday, January 29, 2012 3:41 AM
    • Marked as answer by Carlos052010 Sunday, January 29, 2012 5:03 PM
    Sunday, January 29, 2012 3:41 AM

All replies

  • Hi Carlos,

    You'd be best to use a hashtable to for this. For example:

    $items = @{}
    $items["Status"] = "True"
    $items["State"]  = "Enabled"
    Write-Host $items.Status

    Cheers Matt

     

    Sunday, January 29, 2012 3:15 AM
  • Hi Carlos,

    See the following documentation for further details on how to use hashtables:

    http://technet.microsoft.com/en-us/library/ee692803.aspx

    http://technet.microsoft.com/en-us/library/dd315369.aspx

    Cheers Matt :)

    Sunday, January 29, 2012 3:18 AM
  • Not sure I follow.  If I have this array below, how do I get the value of the element that is always 2 down from the element that has the value of Status.  In this case I want a variable that will have the value of 6 since it is two down from the element that has the value Status in my example below.

    $items = @{1, 2, 3, Status, 5, 6, 7}
    $value = 6

     


    Sunday, January 29, 2012 3:20 AM
  • I got the value in a round about way by finding the index, incrementing it by 2, and getting the value of the array at that index. 

     

    $status = 0..($items.Count - 1) | Where { $items[$_] -eq $status }

    $valueline = $status + 2

    $items[$valueline]

    • Marked as answer by Carlos052010 Sunday, January 29, 2012 3:41 AM
    • Unmarked as answer by Carlos052010 Sunday, January 29, 2012 3:41 AM
    • Marked as answer by Carlos052010 Sunday, January 29, 2012 5:03 PM
    Sunday, January 29, 2012 3:41 AM
  • What was the value of $status before the code below was executed?
    What was the value of $items before the code below was executed?
     
    On 1/28/2012 9:41 PM, Carlos052010 wrote:
    > I got the value in a round about way by finding the index, incrementing it by 2, and getting the
    > value of the array at that index.
    >
    > $status = 0..($items.Count - 1) | Where { $items[$_] -eq $status }
    >
    > $valueline = $status + 2
    >
    > $items[$valueline]
    >
     
     
    Sunday, January 29, 2012 4:53 AM
  • $items = @{1, 2, 3, Status, 5, 6, 7}

    $status equals 3 because the index of the element in the above array with the value of Status is 3. 

    $valueline is 5 which is 3 + 2

    $items[5] is the value of 6

    Sunday, January 29, 2012 5:14 AM
  • Are you sure?
     
    Can you show the entire set of lines of PowerShell code?
     
    If I'm following so far, here is what I have, and it is not valid PowerShell code:
     
    $items = @{1, 2, 3, Status, 5, 6, 7}
    $status = 0..($items.Count - 1) | Where { $items[$_] -eq $status }
    $valueline = $status + 2
    $items[$valueline]
     
     
    Sunday, January 29, 2012 5:27 AM
  • That looks almost right.  Do you mean something like this?

    $status = 'Status'   # known element
    $knownIndex = 0..($items.Count - 1) | where {$items[$_] -eq $status}  # find index of known element
    $newIndex = $knownIndex + 2
    $newValue = $items[$newIndex]

    Another way would be with a loop:

    $newValue = `
    for($i = 0; $i -lt $items.Count; $i++)
    {
       if($items[$i] -eq 'Status'){ $items[$i + 2]; break }
    }

    Or even using Select-String:

    $selected = $items | select-string 'Status' -context 0,2
    $newValue = $selected.Context.PostContext[1]

    Note that you need to be careful if perhaps 'Status' exists more than once in your array...

    Thanks,
    -Lincoln

    • Proposed as answer by Larry Weiss Sunday, January 29, 2012 6:50 PM
    Sunday, January 29, 2012 6:17 AM
  • Going back to the original question:

    "How would I search the array for this value and then get the value of the item that is 2 spots past it?"

    This is how I would go about it:

     

    $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    $items[$items.IndexOf('Status')+2]
    

     


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script


    • Edited by Bigteddy Sunday, January 29, 2012 7:16 AM
    Sunday, January 29, 2012 6:54 AM
  • I get an error using that solution
     
    C:> $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    C:> $items[$items.IndexOf('Status')+2]
    Method invocation failed because [System.Object[]] doesn't contain a method nam
    ed 'IndexOf'.
    At line:1 char:22
    + $items[$items.IndexOf <<<< ('Status')+2]
        + CategoryInfo          : InvalidOperation: (IndexOf:String) [], RuntimeEx
       ception
        + FullyQualifiedErrorId : MethodNotFound
     On 1/29/2012 12:54 AM, Bigteddy wrote:
    > Going back to the original question:
    >
    > "How would I search the array for this value and then get the value of the item that is 2 spots
    > past it?"
    >
    > This is how I would go about it:
    >
    > $items  =  @(1, 2, 3,'Status', 5, 'Value to find')
    > $items[$items.IndexOf('Status')+2]
    >
     
    Sunday, January 29, 2012 4:42 PM
  • Larry, this is a basic array operation.  I can't reproduce your error.  I works fine on my system.  And it makes perfect sense. This is so basic, if you can't use the the .IndexOf on a array, you have a problem.
    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script


    • Edited by Bigteddy Sunday, January 29, 2012 4:50 PM
    Sunday, January 29, 2012 4:47 PM
  • Also, using my recently favorite "hammer", the switch statement:
     
    C:> $status = 'Status'
    C:> $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    C:> $n=0; switch ($items){ {$_ -eq $status} {$items[$n+2]} default {$n++}}
    Value to find
     
     
    • Proposed as answer by Larry Weiss Sunday, January 29, 2012 6:50 PM
    Sunday, January 29, 2012 4:54 PM
  • See:
     
     
    It seems that IndexOf is a String object method only.
     
    On 1/29/2012 10:47 AM, Bigteddy wrote:
    > Larry, this is a basic array operation. I can't reproduce your error. I works fine on my system.
    > And it makes perfect sense. This is so basic, if you can't use the the .IndexOf on a array, you
    > have a problem.
     
     
    Sunday, January 29, 2012 4:59 PM
  • You don't need to do all that.  That's my point.  We have an array - the OP suggested that's what we start with.  If you need to find the index of any array, you can use (most efficiently) .IndexOf.  That's what arrays were built for:  To be queried.

    No loops are needed.  It's all built-in to the functionality of an array, of which we already have one.  So we are graciously given the .IndexOf method, and if we choose to ignore it, then may our code suffer accordingly.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 4:59 PM
  • Larry, this is a basic array operation.  I can't reproduce your error.  I works fine on my system.  And it makes perfect sense. This is so basic, if you can't use the the .IndexOf on a array, you have a problem.
    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script



    I can reproduce this error,because the IndexOf is a static method.

    [array]::IndexOf($items,"Status) - works fine

    Sunday, January 29, 2012 5:01 PM
  • I tried his method of...

     

    $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    $items[$items.IndexOf('Status')+2]
    
     on my system and it works fine. 
    $items in this case has 2 methods to deal with indexes...
    IndexOf          Method                int IndexOf(char value), int IndexOf(...
    IndexOfAny       Method                int IndexOfAny(char[] anyOf), int Ind...
    Sunday, January 29, 2012 5:03 PM
  • I have the same issue as Larry. Are you using v2 or v3?
    Sunday, January 29, 2012 5:03 PM
  • # That is clearly incorrect, as the following code shows:
    [array]$ThisIsAnArray = 1..10
    $ThisIsAnArray.IndexOf(5) #prints 4 (zero based array)
    


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    • Edited by Bigteddy Sunday, January 29, 2012 5:06 PM
    Sunday, January 29, 2012 5:04 PM
  • By the way, we needn't have cast 1..10 as an array.  That was just to prove the point.  $ThisIsAnArray would have automatically been cast into an array, as a little experimentation will prove.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 5:17 PM
  • I get reasonable results with the static method named IndexOf called using the two arguments, but
    not as a method named IndexOf of an array object.   I'm using PowerShell V2
     
    C:> $(1..10).IndexOf(1)
    Method invocation failed because [System.Object[]] doesn't contain a method nam
    ed 'IndexOf'.
    At line:1 char:17
    + $(1..10).IndexOf <<<< (1)
        + CategoryInfo          : InvalidOperation: (IndexOf:String) [], RuntimeEx
       ception
        + FullyQualifiedErrorId : MethodNotFound
     
    C:> [array]::IndexOf($(1..10),1)
    0

     
     On 1/29/2012 11:01 AM, Kazun [MVP] wrote:
    > I can reproduce this error,because the IndexOf is a static method.
    > [array]::IndexOf($items,"Status) - works fine
    >
     
     


    • Edited by Larry Weiss Sunday, January 29, 2012 5:27 PM
    Sunday, January 29, 2012 5:25 PM
  • Maybe because I'm on V3?  Need more time to understand and investigate why you guys are getting different results to me.

    I started a fresh Powershell instance to test my proposed code, and it worked fine.  So it's not like my variables are already defined.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    • Edited by Bigteddy Sunday, January 29, 2012 5:30 PM
    Sunday, January 29, 2012 5:29 PM
  • You are from the future!  <grin>
     
    On 1/29/2012 11:29 AM, Bigteddy wrote:
    > Maybe because I'm on V3?
     >
     
    Sunday, January 29, 2012 5:34 PM
  • See screen-shot (V3 ISE) :


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 5:41 PM
  • I tried his method of...

     

    $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    $items[$items.IndexOf('Status')+2]
    
     on my system and it works fine. 
    $items in this case has 2 methods to deal with indexes...
    IndexOf          Method                int IndexOf(char value), int IndexOf(...
    IndexOfAny       Method                int IndexOfAny(char[] anyOf), int Ind...

    "IndexOfAny" sounds interesting.  Maybe what the OP really needs? ...
    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 6:00 PM
  • How so?
     
    I think that if an IndexOf style solution is preferred, that it would be this one
     
    C:> $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    C:> $items[[array]::IndexOf($items,'Status') + 2]
    Value to find
     
    On 1/29/2012 12:00 PM, Bigteddy wrote:
    >
    > "IndexOfAny" sounds interesting. Maybe what the OP really needs? ...
     >
     
     
    • Proposed as answer by Larry Weiss Sunday, January 29, 2012 6:51 PM
    Sunday, January 29, 2012 6:14 PM
  • So can I honestly say that this is a new feature of Powershell V3?  The .IndexOf as method of a Powershell array, I mean?
    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    • Edited by Bigteddy Sunday, January 29, 2012 6:27 PM
    Sunday, January 29, 2012 6:25 PM
  • I can't find that documented anywhere.
     
    Pragmatically, you seem to have made that discovery.
    I can't make it work in V2.  You can make it work in V3.
    Not much more to say unless we discover the documentation in a list like the one at
     
      On 1/29/2012 12:25 PM, Bigteddy wrote:
    > So can I honestly say that this is a new feature of Powershell V3? The .IndexOf as method of a
    > Powershell array, I mean?
     >
     

    • Edited by Larry Weiss Sunday, January 29, 2012 6:35 PM
    Sunday, January 29, 2012 6:34 PM
  • Maybe because I'm on V3?  Need more time to understand and investigate why you guys are getting different results to me.

    I started a fresh Powershell instance to test my proposed code, and it worked fine.  So it's not like my variables are already defined.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script


    I just checked, and there is no .indexof method on an array in V2, but there is in V3.

     Also, FWIW I got this for a solution:

    0..($array.count-1) |
    foreach {
        if ($array[$_] -eq $status){$array[$_+2]}
        }

     


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    • Edited by mjolinor Sunday, January 29, 2012 6:43 PM
    Sunday, January 29, 2012 6:38 PM
  • I can't find that documented anywhere.
     
    Pragmatically, you seem to have made that discovery.
    I can't make it work in V2.  You can make it work in V3.
    Not much more to say unless we discover the documentation in a list like the one at
     

    If you go there, you'll find a link, right at the bottom, to my pet Wiki, the "What's new in V3"

    Everyone is welcome to contribute to this.  I don't own this Wiki. 


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 6:40 PM
  • I just checked, and there is no .indexof method on an array in V2, but there is in V3.

     

     


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Thanks, mj, for the confirmation.  More grist for the mill, or whatever they say.

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 6:45 PM
  • How so?
     
    I think that if an IndexOf style solution is preferred, that it would be this one
     
    C:> $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    C:> $items[[array]::IndexOf($items,'Status') + 2]
    Value to find
     
    On 1/29/2012 12:00 PM, Bigteddy wrote:
    >
    > "IndexOfAny" sounds interesting. Maybe what the OP really needs? ...
     >
     
     

    IMO, this is the correct answer to the question, bearing in mind V2.
    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 6:58 PM
  • Does it still work on V3 ?
     
    $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    $items[[array]::IndexOf($items,'Status') + 2]
     
     
    Sunday, January 29, 2012 7:30 PM
  • Does it still work on V3 ?
     
    $items = @(1, 2, 3, 'Status', 5, 'Value to find')
    $items[[array]::IndexOf($items,'Status') + 2]
     
     

    Yes, tried it, expected results.
    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 7:43 PM
  • Grant, thanks for testing it.
     
    Sunday, January 29, 2012 7:44 PM
  • Grant, have you found anything yet that does not work in V3 that works in V2?
     
     
    Sunday, January 29, 2012 7:45 PM
  • Grant, have you found anything yet that does not work in V3 that works in V2?
     
     


    No, nor would I expect to.  Everything is backward-compatible, AFAIK.  As a learning tool, V3 ISE is just the best.  The intellisense is great, and helps to write code quickly.

    I hardly ever have to use Get-Member anymore!

    For example, let's say I declare an array in the ISE:

    $array = 1..10

    ...Press F5, and subsequent $array. commands are helped by intellisense, because it now knows what $array is.

    I highly recommend this release, just for the intellisense alone.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 7:52 PM
  • Having said that, when I have to write scripts on V2, I now find it painful.  It makes one lazy, in a way, if by lazy one means more efficient, if you see what I mean!

    And did you know that Get-Member has a -View all parameter?

    dir | gm -view all

     


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Network Live Audit - Powershell script
    Sunday, January 29, 2012 7:58 PM
  • This is not new in powershell v3, it's new in .NET 4 (PS v3 was just the first version where .NET 4 is supported and loaded by default).  If you use one of the various workarounds to load .NET 4 into powershell v2 you will get this method there, as well.

    There are a bunch of goodies on array instances availabe in .NET 4 vs 3.5.  Open a v2 shell (powershell.exe -version 2) and a v3 shell and try this in each:

    $array = 1..10
    ,$array | gm


    Thanks,
    -Lincoln


    This is  feature available only in V3.

    PS >  $PSVersionTable
    
    Name                           Value
    ----                           -----
    PSVersion                      2.0
    PSCompatibleVersions           {1.0, 2.0}
    BuildVersion                   6.1.7601.17514
    PSRemotingProtocolVersion      2.1
    WSManStackVersion              2.0
    CLRVersion                     4.0.30319.239
    SerializationVersion           1.1.0.1
    
    
    PS >  ,@(1..10) | gm indexof
    PS >  ,@(1..10) | gm -static indexof
    
    
       TypeName: System.Object[]
    
    Name    MemberType Definition
    ----    ---------- ----------
    IndexOf Method     static int IndexOf(array array
    

     

    Monday, January 30, 2012 8:53 PM
  • You are right, I was too hasty.  Thanks for making me take a second look.  They have indeed added some custom methods/properties only in powershell.  And there doesn't appear to be an obvious way to differentiate btw "real" members and custom ones added by powershell...  Besides something like this

    $array.gettype().getmethods() | select -expand Name | sort -unique
    ,$array | gm -membertype Method -force | select -expand Name | sort -unique

    Monday, January 30, 2012 10:45 PM
  • Here is my diagram of the parameters available with Get-Member
     
    Get-Member | gm
      [[-Name] <string[]>]
      [-Force]
      [-InputObject <psobject>]
      [-MemberType {
                               AliasProperty
                               CodeProperty
                               Property
                               NoteProperty
                               ScriptProperty
                               Properties
                               PropertySet      
                               Method
                               CodeMethod
                               ScriptMethod
                               Methods
                               ParameterizedProperty
                               MemberSet
                               Event
                               All
                             } ]
      [-Static]
      [-View {
                   Extended
                   Adapted
                   Base
                   All
                 } ]
      [<CommonParameters>]

     
     On 1/29/2012 1:58 PM, Bigteddy wrote:
    > And did you know that Get-Member has a -View all parameter?
    >
    > dir | gm -view all
    >
     



    • Edited by Larry Weiss Wednesday, February 1, 2012 2:07 AM
    Wednesday, February 1, 2012 1:49 AM
  • Hi Carlos

    Try this....

    $SampleArray="Status","Here","Is","A","Hypothetical","Array"

    $i=0
    Foreach($ArrVal in $SampleArray){
        $i=$i++
        If($ArrVal -eq "Status"){
            $valueat2down=$i+2
        }
    }
    $SampleArray[$valueat2down]

    Regards Ram
    Wednesday, February 1, 2012 9:07 AM
  • You do realize a switch statement is just a tarted up hash table of script blocks, right?


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Wednesday, February 1, 2012 12:13 PM
  • Can you show the un-tarted up hash table equivalent to my code so I can be sure I understand?
     
    Wednesday, February 1, 2012 1:26 PM
  • $hash = @{
    Status = {$items[$n+2]}
    default = {$n++}
    }
    
    
    if ($hash.$_){&$hash.$_}
    else {&$hash.default}
    


    Table keys are the tests, and the key values are the script block to execute.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Wednesday, February 1, 2012 2:08 PM
  • No, it's not.  In compiled languages it is, but not in powershell.  In powershell a switch statement is syntactic sugar for a series of if blocks

    switch($thing)
    {
       $pattern1{ do this 1}
       $pattern2{ do this 2 }
       default{ do this default }
    }

    is implemented under the covers as

    if($thing matches $pattern1){ do this 1 ; $doDefault = $false;}
    if($thing matches $pattern2){ do this 2; $doDefault = $false; }
    if($doDefault){ do this default }

    That's how powershell can offer all of the neato options like regex switch and wildcard switch, and how multiple pattern blocks can be executed in a single pass.  Unlike compiled languages, switch is actually a rather slow option in powershell due to the fact that it will check the input against every single pattern every time (unless you use continue/break).  Writing your own series of if/elseif blocks is better if performance is the main goal.

    Thanks,
    -Lincoln

    Wednesday, February 1, 2012 2:41 PM
  • Thanks.  I stand corrected. 

    But the hash table of script blocks does appear to work without needing to iterate through the keys if you're doing a direct compare (not wildcard or regex matching).

    I wonder how using that would compare performance-wise to doing the same thing with a stack of if/else blocks.

     


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Wednesday, February 1, 2012 2:54 PM
  • I think that one problem to overcome is that each scriptblock in the hash table key values creates
    a local context for variables like $n when it is executed.
     
    .
    On 2/1/2012 8:08 AM, mjolinor wrote:
    > $hash  =  @{
    > Status=  {$items[$n+2]}
    > default=  {$n++}
    > }
    >
    > if  ($hash.$_){&$hash.$_}
    > else  {&$hash.default}
    >
    > Table keys are the tests, and the key values are the script block to execute.
    >
     
    Wednesday, February 1, 2012 3:34 PM
  • You'd have to take that into consideration. 

    I ran some quick tests, and using if($ hash.$_) to validate is a bad idea.  if ($hash.containskey($_)) is much better.

    On a test stack of 20 tests, one using if/elseif /else and one using a hash table with random data and empty script blocks (to eliminate everything but the  time to select the right script block) the hash table tested about 50% faster if you include the validation and default.  If you don't need to validate and use the default (no if, just &$hash.$_) it's about twice as fast.

    I'd have to run some more tests to say for sure if it's any better,  The if/else could easily be faster than the hash table if you know that the incoming data will be skewed to a high incidence of particular values, and you put those tests at the top of the stack.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Wednesday, February 1, 2012 4:00 PM
  • Yes, you are certainly right that a hashtable of scriptblocks is a nice MacGyver'ed version of a switch statement with direct equality compares :-)

    Performance of that, as it seems your tests indicate, should actually be good compared to if/elseif.  Hash lookup is O(1) in that it takes the same amount of time regardless of how many guy are in the hashtable.  A series of if/elseifs might match on the first one, or maybe the last one.  It's O(n) in that the average number of blocks that need to be checked goes up linearly with the number of total blocks.  Of course, if you know ahead of time that most data will match in the first couple blocks, then this gets skewed, but you get the idea.

    Cool to see your data back that up.  The theory says that adding 20 new entries to your hash table won't affect speed there, but adding 20 new elseif blocks (in random places) will roughly double the runtime of that option.

    The caveat for all of this is that except for rather large data sets, the differences won't be practically noticeable.  It's often a tradeoff between best possible perf and simplicity/maintainability.  There is a lot to be said for the easy readability of a switch statement, even if it's not the fastest construct available.  It's up to the scripter to decide where the right balance is.

     

    Wednesday, February 1, 2012 5:55 PM
  • Thanks for your thoughts.

     

    As long as I've got it set up, I'll post it to a new discussion thread.  This one is getting way off topic.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Wednesday, February 1, 2012 7:07 PM