PowerShell自定义函数向$computers数组添加对象报索引越界
索引越界报错的产生原因
- PowerShell 中数组采用0起始索引规则,从
Import-Csv导入得到的是固定大小的.NET原生数组,有效索引范围为0 ~ 数组总长度-1,不支持直接通过超范围索引赋值完成扩容。 - 代码中
$computers[$computers.count+1] = $newObject的索引计算存在两个核心错误:- 就算是在数组末尾追加元素,符合逻辑的末尾位置索引是
$computers.Count(因为最后一个元素的索引是$computers.Count -1,后续空位刚好对应总长度数值的索引),代码多写了+1,直接指向了不存在的索引位置。 - 固定大小数组本身长度固定,不支持在数组边界外的位置赋值,只要索引超出有效范围,PowerShell就会直接抛出索引越界异常。
- 就算是在数组末尾追加元素,符合逻辑的末尾位置索引是
- 代码中手写的for循环逻辑属于完全冗余实现:循环的目的是定位数组末尾,但定位完成后的赋值操作本身就会触发越界报错,没有任何实际作用。
- 原实现还有一个隐藏逻辑缺陷:就算成功追加了对象,也没有执行导出CSV的操作,所有修改仅存在于函数的局部内存中,函数退出后修改就会丢失,不会永久保存到CSV文件里。
正确实现方案
根据数据量大小可以选择两种适配的实现方式,两种方式都不需要手动计算数组索引:
- 小数据量场景(CSV条目数在千条以内):直接使用PowerShell内置的数组拼接运算符
+=完成追加,语法简单易维护。 - 大数据量场景(CSV条目数过万):使用支持动态扩容的泛型List集合追加,避免反复生成新数组的性能损耗。
基础版实现(适合小数据量)
function ajouterperipherique ($id, $emplacement, $type) { $csvPath = "C:\Temp\Peripherique.csv" # 读取CSV原有数据 $computers = Import-Csv -Path $csvPath Write-Host "CSV当前原有数据:" $computers | Format-Table -AutoSize | Out-Host # 构造待追加的自定义对象 $newObject = [pscustomobject]@{ idObject = $id EmplacementObject = $emplacement TypeObject = $type } # 直接拼接追加新对象,自动处理数组长度适配 $computers += $newObject # 将更新后的全量数据写回CSV文件,永久保存修改 $computers | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8 Write-Host "已成功追加新对象:" $newObject | Format-List | Out-Host } # 调用函数执行追加 ajouterperipherique "GLADIATOR" "ordinateur" "Statique"
高性能版实现(适合大数据量)
function ajouterperipherique ($id, $emplacement, $type) { $csvPath = "C:\Temp\Peripherique.csv" # 初始化支持动态扩容的泛型对象集合 $computerList = [System.Collections.Generic.List[psobject]]::new() # 将读取到的原有CSV数据批量加载到动态集合中 $computerList.AddRange((Import-Csv -Path $csvPath)) # 构造待追加的自定义对象 $newObject = [pscustomobject]@{ idObject = $id EmplacementObject = $emplacement TypeObject = $type } # 直接调用集合的Add方法追加元素,无额外数组拷贝开销 $computerList.Add($newObject) # 将更新后的全量数据写回CSV文件 $computerList | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8 Write-Host "已成功追加新对象:" $newObject | Format-List | Out-Host } # 调用函数执行追加 ajouterperipherique "GLADIATOR" "ordinateur" "Statique"
注意:使用
Export-Csv的时候建议加上-Encoding UTF8参数,避免中文内容导出后出现乱码;加上-NoTypeInformation参数,避免CSV开头出现多余的类型描述行。
内容的提问来源于stack exchange,提问作者user15481754
相关产品推荐
相关产品推荐

