0

How to write function which get array as object from pipeline (actually any object) without to iterate over its items and another one argument (positional). Goal is to modify container (array), but not their items. Something like:

function xxx {
  Param( magic-specification??? )
  if ($obj type is array) {
    iterate over $obj items {
      $res = executes $args[0] script-block over them ($_)
      if ($res) modify $obj
    }
  else if ($obj type is object) {
    iterate over $obj properties {
      $res = executes $args[0] script-block over them ($_)
      if ($res) modify $obj property
    }
  }
4
  • there are at least 4 ways [grin] - [1] wrap the array in another array ///// [2] prefix the array with the <comma> array operator ///// [3] use the -InputObject parameter if it has one ///// [4] use a $Script: scoped $Var. Commented Nov 1, 2018 at 10:34
  • 1, 2, 3 assume to pass array as argument and not through piping, did I got you right? Commented Nov 1, 2018 at 10:37
  • So, no way to pass array instead of its items over pipe, right? Is this the reason why "where" has -InputObject optional argument? Commented Nov 1, 2018 at 10:40
  • 1
    PoSH unwraps a collection before sending it to the pipeline. so, to stop it doing that, you have to wrap the array in another array so THAT one is unwrapped. the pipeline is DESIGNED to work on the items in collections, so you have to really work at it to get around that design goal. [grin] Commented Nov 1, 2018 at 12:01

1 Answer 1

2

here's a demo of how to bypass the way that PoSh is intended to unroll items sent across the pipeline ...

,@(1,2,3) | ForEach-Object {$_.GetType(); "$_" } | Out-Host
@(1,2,3) | ForEach-Object {$_.GetType(); "$_" } | Out-Host
1,2,3 | ForEach-Object {$_.GetType(); "$_" } | Out-Host

output ...

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
1 2 3


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType
1
True     True     Int32                                    System.ValueType
2
True     True     Int32                                    System.ValueType
3


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType
1
True     True     Int32                                    System.ValueType
2
True     True     Int32                                    System.ValueType
3

note that the 1st one has passed thru an array while the others all unrolled the array. that leading , is the array operator and it causes PoSh to send the array wrapped in another array. the outer one gets unrolled, the inner one gets passed on as an array.

Sign up to request clarification or add additional context in comments.

6 Comments

Great answer. One other way is using write-output -NoEnumerate. write-output 1,2,3 -NoEnumerate| ForEach-Object {$_.GetType(); "$_" } | Out-Host
@MikeShepard - yep, that works ... and i never seem to remember it. [blush] plus, it is rather non-obvious. [grin]
I just showed a group that. Didn't even think of the "leading-comma" trick at the time. To me, that's less obvious than saying "don't enumerate this". We were dealing with function output, though.
@MikeShepard - the "not obvious" is that i would not think of anything not fairly directly related to arrays. your solution is nifty but i would never think to look at Write-Output -NoEnumerate to find that workaround. [grin]
makes sense. I remembered it rather than finding it when I needed it (if that makes sense).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.