为何无法用Remove()从ArrayList删除嵌套数组?如何实现删除?
问题原因
System.Collections.ArrayList的Remove()方法默认使用引用相等性匹配元素:
- 对于int、string这类值类型(或字符串这种特殊的不可变引用类型),PowerShell会自动按值判断相等性,所以能正常找到并删除目标元素。
- 但数组属于引用类型,你定义的
$myObj = @(0,1)和ArrayList里的@(0,1)是两个完全独立的对象,内存引用地址不同,因此Remove()无法找到匹配项。
实现删除的方法
方法1:按值匹配找到元素后删除
利用ArrayList的Find()方法自定义值相等判断逻辑,定位目标元素后执行删除:
[System.Collections.ArrayList]$al = @(@(0,1),@(1,2),@(3)) $myObj = @(0,1) # 找到值完全匹配的元素 $target = $al.Find({ param($item) ($item.Count -eq $myObj.Count) -and (-not (Compare-Object $item $myObj -SyncWindow 0)) }) if ($target) { $al.Remove($target) } # 验证结果 $al
方法2:先获取元素索引再删除
用FindIndex()定位目标元素的索引,再调用RemoveAt()删除,这种方式性能更优:
[System.Collections.ArrayList]$al = @(@(0,1),@(1,2),@(3)) $myObj = @(0,1) $index = $al.FindIndex({ param($item) if ($item.Count -ne $myObj.Count) { return $false } # 逐个元素比较值 for ($i=0; $i -lt $item.Count; $i++) { if ($item[$i] -ne $myObj[$i]) { return $false } } return $true }) if ($index -ne -1) { $al.RemoveAt($index) } # 验证结果 $al
方法3:筛选后重新赋值ArrayList
如果不需要保留原ArrayList对象,可直接筛选出非目标元素重新赋值:
[System.Collections.ArrayList]$al = @(@(0,1),@(1,2),@(3)) $myObj = @(0,1) $al = $al | Where-Object { $item = $_ if ($item.Count -ne $myObj.Count) { return $true } # 检查所有元素值是否匹配 $isMatch = $true for ($i=0; $i -lt $item.Count; $i++) { if ($item[$i] -ne $myObj[$i]) { $isMatch = $false; break } } -not $isMatch } # 验证结果 $al
内容的提问来源于stack exchange,提问作者Philippe Hebert
相关产品推荐
相关产品推荐

