鸭子在Powershell中为索引的iteratables打字

时间:2017-09-01 12:30:07

标签: powershell duck-typing

而不是管道集合,有时在程序上循环它们更方便。并且为了避免根据输入区分$_$_.Key / $_.Value,更一致的键/值处理会很好:

ForEach-KV $object { Param($k, $v); do-stuff }

然而,普通类型的探测有其缺点:

#-- iterate over dicts/objects/arrays using scriptblock with Param($k,$v)
function ForEach-KV {
    Param($var, $cb, $i=0)
    switch ($var.GetType().Name) {
        Array          { $var | % { $cb.Invoke($i++, $_) } }
        HashTable      { $var.Keys | % { $cb.Invoke($_, $var[$_]) } }
       "Dictionary``2" { $var.Keys | % { $cb.Invoke($_, $var.Item($_)) } }
        PSobject       { $var.GetIterator() | % { $cb.Invoke($_.Key, $_.Value) } }
        PSCustomObject { $var.GetIterator() | % { $cb.Invoke($_.Key, $_.Value) } }
        default        { $cb.Invoke($i++, $_) }
    }
}

除了那个令人恼火的类型名称之外,这里有一点重复。这就是我在Powershell中寻找鸭子打字的原因。

对于哈希和对象,探测.getIterator.getEnumerator是最简单/最明显的(绝不能完全记住哪个属于哪个):

switch ($_) {
    { $_.GetEnumerator }  { do-loopy }
    { $_.GetIterator }    { do-otherloopy }

但现在我不太清楚如何处理数组。 [array]方法中的 行为指标并非

  • .Get()确实看起来很独特(至少不是HashTables或PSObjects中的方法),但即使对于类型猜测,它听起来有点太通用
  • .Add()也可能是整数方法(?)
  • .GetUpperBound()等已经有点过于具体了。

那么,是否有一种标准方法可以说" arrayish",最好是在其他数字索引的价值集合中共享的东西?

1 个答案:

答案 0 :(得分:1)

如果您只想匹配数组:

PS> $x = 1..10
PS> $x.GetType().IsArray
True

或者您可以检查是否存在整数索引器:

(Get-Member -InputObject $x -Name 'Item' -MemberType 'ParameterizedProperty').Definition -match '\(int index\)'