【问题标题】:Removing element from .NET array .remove method not working as expected (Powershell)从 .NET 数组中删除元素 .remove 方法未按预期工作(Powershell)
【发布时间】:2013-05-24 16:58:29
【问题描述】:

我有一些代码,我试图在 Powershell 中使用 .NET 方式处理数组,而 .remove 方法没有删除我想要的元素(示例 2 和 3 中的进程名称“wssm”)。我做错了什么,我不确定它是什么。

  1. 当我使用 .add 填充特定元素时,测试示例有效:

    -----------EX1------------

    $foo = New-object System.Collections.Arraylist
    
    $foo.add("red")
    
    $foo.add("blue")
    
    $foo.remove("red")
    

    $foo 返回单个元素值“蓝色”(这很好)。

  2. 当我尝试使用 Get-process 的结果填充数组(使用以下两种不同的方法)并尝试删除元素值“wssm”时,它似乎无法找到并删除它。

    ------------EX2--------------

    $test = New-object System.Collections.Arraylist(,(get-process |select processname))
    
    $test.Remove("wssm")
    

    -------------EX3------------

    $test = New-object System.Collections.Arraylist
    
    $test2= get-process |select processname 
    
    $test.Addrange($Test2)
    
    $test.Remove("wssm")
    

示例 2 和示例 3 不删除包含“wssm”的元素,只返回进程名称的整个数组列表(wssm 显示为存在于数组中)并且不会引发错误。

当我做一个

$foo |get-member

返回:

TypeName: System.String

并且 .remove 被列为一种方法。当我做一个:

$test |get-member

返回:

TypeName: Selected.System.Diagnostics.Process

并且 .remove 没有被列为方法(为什么不抛出错误是未知的)。

$foo 的结果不包含标题,$test 的结果包含来自我的 get-process 步骤中选择的“processname”标题。

这是一个多维数组问题,我只是在 .remove("wssm") 步骤中没有使用正确的语法?还是我应该以不同的方式声明数组?

感谢您的帮助。

【问题讨论】:

  • 数组没有传递给Get-Member,数组的每个元素都传递给它。这意味着您找到的 Remove 是 String.Remove,而不是 ArrayList.Remove

标签: arrays powershell element


【解决方案1】:

当您使用Get-Process 的输出填充ArrayList 时,您正在创建一个对象数组。使用字符串“wssm”调用Remove() 方法不会做任何事情,因为数组不包含这样的字符串对象。相反,您需要使用该进程名称识别对象并将该对象从数组中删除:

$wssm = $test | ? { $_.ProcessName -eq "wssm" }
$test.Remove($wssm)

【讨论】:

  • 这行得通,但也可以这样做$test = $test | ? { $_.ProcessName -ne "wssm" }
  • 这也是一种选择,是的。
  • 那些太棒了!非常感谢。所以我什至不必使用 .NET 形式的数组。我听说在本机 powershell 中删除元素并不容易,但重新复制减去你不想要的元素似乎效果很好。
【解决方案2】:

我看到有人写了这段代码,但后来删除了:

$test = New-object System.Collections.Arraylist(,(get-process |select -expandProperty processname))

这很好,但不知道为什么会被删除。

如果我们不扩展属性,新对象“类型”似乎将由“get-process”决定,即“System.Diagnostics.Process”。

$test = New-object System.Collections.Arraylist(,(get-process |select  processname))

当我们使用“-expandProperty”时,它变成了system.string:

$test = New-object System.Collections.Arraylist(,(get-process |select -expandProperty processname))

实际上,这是一个很好的例子,展示了 expandProperty 的工作原理。

【讨论】:

  • 也许用户删除了这个问题,因为我的评论是扩展属性会将字符串而不是进程对象放入数组中。这可能是不希望的,具体取决于 OP 想要对该数组做什么。
猜你喜欢
  • 2017-02-15
  • 2020-03-12
  • 2019-06-22
  • 2023-03-16
  • 1970-01-01
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多