创建通过Powershell循环的函数

创建通过Powershell循环的函数,powershell,Powershell,我试图创建一个函数来循环json文件,并根据满足的特定条件,希望将json键的值添加到数组中,但无法完成相同的操作 以下是json: $a1 = [ { "name": "sachin", "surname": "", }, { "name": "Rajesh", "surname": "Mehta" } ] 我创建的函数如下所示: function addingkeyval { param ($k

我试图创建一个函数来循环json文件,并根据满足的特定条件,希望将json键的值添加到数组中,但无法完成相同的操作

以下是json:

$a1 = [    {
        "name": "sachin",
        "surname": "",
    },
    {
        "name": "Rajesh",
        "surname": "Mehta"

    }
]
我创建的函数如下所示:

function addingkeyval
{
param ($key,
        [Array]$tobeaddedarr)

$a1 | Select-Object -Property name,surname | ForEach-Object {
    if($_.$key-eq "")
    {
    }
    else
    {     
    $tobeaddedarr +=$_.$key+","
    }
}

}
当我用语句调用此函数时:

$surnamearr = @()
addingkeyval -key surname -tobeaddedarr $surnamearr

i want the output in the array $surnamearr as below
("Mehta")

不知何故,我无法在数组中添加值。有人能帮我实现相同的功能吗?

如果您只需要一个姓氏数组,您可以这样做

$a1='[
{
“名称”:“sachin”,
“姓氏”:“,
},
{
“姓名”:“拉杰什”,
“姓氏”:“梅塔”
}
]'
$Json=$a1 |从Json转换
$namess=$Json|
其中,对象{$null-ne$\姓氏-和![string]::IsNullOrEmpty($\姓氏)}
选择对象-属性姓氏

若您只需要一组姓氏,可以这样做

$a1='[
{
“名称”:“sachin”,
“姓氏”:“,
},
{
“姓名”:“拉杰什”,
“姓氏”:“梅塔”
}
]'
$Json=$a1 |从Json转换
$namess=$Json|
其中,对象{$null-ne$\姓氏-和![string]::IsNullOrEmpty($\姓氏)}
选择对象-属性姓氏
  • ConvertFrom Json$a1
    将Json数组转换为PowerShell自定义对象数组(键入
    [pscustomobject]

  • (…).shuname
    使用提取结果数组中对象的所有
    .shuname
    属性的值

  • Cast
    [string[]
    确保将结果视为数组(如果
    $a1
    中的数组恰好只包含一个元素,则不会是数组),并显式强制转换为字符串,因此,通过
    -ne'
    过滤非空值也适用于恰好没有
    姓氏属性的输入对象

  • -ne'
    从生成的数组中过滤掉所有空字符串元素(将数组作为LHS,比较运算符(如
    -ne
    )充当数组过滤器,而不是返回布尔值)

结果是,
$namesarr
是一个数组,包含所有非空的
.namesname
属性值


至于你所尝试的:

$tobeadedarr+=$.$key+,“

此语句隐式创建一个新数组,与调用方通过
$tobeadedarr
参数变量传递的数组引用不同-因此,调用方从未看到更改

通常无法传递要就地追加的数组,因为数组的元素数是不可变的

虽然您可以传递一个类似数组的可变结构(例如
[System.Collections.Generic.List[object]]]
实例,您可以使用它的
.Add()
方法将其附加到该实例中),但在函数中构建一个新数组并输出它要简单得多

因此,您可以将函数编写为:

function get-keyval
{
  param ($key)

  # Implicitly output the elements of the array output by using this command.
  ([string[]] (ConvertFrom-Json $key).surname) -ne ''
}

$surnamearr = get-keyval surname
注:

  • 默认情况下,在PowerShell中输出数组或集合会枚举它:它会将其元素逐个发送到输出流(管道)

    • 虽然可以通过
      的一元形式整体输出数组,但数组构造运算符(
      ,(([string[](ConvertFrom Json$a1.summan)-ne“”)
      ),这提高了性能,问题是调用方可能不会期望这种行为,尤其是在管道中
  • 如果您在变量中捕获输出,例如这里的
    $namesarr
    ,PowerShell会自动为您收集
    [object[]
    数组中的各个输出对象;但是,请注意,单个输出对象按原样返回,即未包装在数组中

    • 您可以围绕函数调用包装
      @(…)
      ,以确保始终获得数组
    • 或者,键入约束接收变量:
      [array]$namesarr=…
      ,这也会创建一个
      [object[]]
      数组,或者类似于
      [string[]]$namesarr=…
      的东西,它会创建一个强类型字符串数组
  • ConvertFrom Json$a1
    将Json数组转换为PowerShell自定义对象数组(键入
    [pscustomobject]

  • (…).shuname
    使用提取结果数组中对象的所有
    .shuname
    属性的值

  • Cast
    [string[]
    确保将结果视为数组(如果
    $a1
    中的数组恰好只包含一个元素,则不会是数组),并显式强制转换为字符串,因此,通过
    -ne'
    过滤非空值也适用于恰好没有
    姓氏属性的输入对象

  • -ne'
    从生成的数组中过滤掉所有空字符串元素(将数组作为LHS,比较运算符(如
    -ne
    )充当数组过滤器,而不是返回布尔值)

结果是,
$namesarr
是一个数组,包含所有非空的
.namesname
属性值


至于你所尝试的:

$tobeadedarr+=$.$key+,“

此语句隐式创建一个新数组,与调用方通过
$tobeadedarr
参数变量传递的数组引用不同-因此,调用方从未看到更改

通常无法传递要就地追加的数组,因为数组的元素数是不可变的

虽然可以传递类似于数组的可变结构(如
[System.Collections.Generic.List[object]]]
实例,您可以使用其
.Add()
方法将其附加到该实例中),但在函数中构建新数组要简单得多
function get-keyval
{
  param ($key)

  # Implicitly output the elements of the array output by using this command.
  ([string[]] (ConvertFrom-Json $key).surname) -ne ''
}

$surnamearr = get-keyval surname