使用 "Select" 导出 CSV 文件时的 Lazy-Pipe-Evaluation
Lazy-Pipe-Evaluation when using "Select" to export CSV file
预期的脚本输出:我想从 Microsoft SharePoint 列表中导出包含特定列的 CSV 文件。
脚本大纲:
首先,我获取 $items
:
中的列表项
$query = New-Object Microsoft.SharePoint.Client.CamlQuery
$items = $list.GetItems($query)
输出 CSV 文件的列在哈希图中定义 $h
($displayName => $internalName
)。
现在我为每一列创建一个新的 Hashtable 并将其添加到 $selects
:
$selects = @()
foreach ($h in $mapping.GetEnumerator()) {
$selects += @{ L = $h.Name; E = { $_[$h.Value] } }
}
然后我导出 CSV 文件:
$items | Select-Object $selects | Export-Csv -Path $outputPath
现在的问题:
在 E 中,我定义了一个表达式,仅在我需要时才计算它(懒惰地,因此在执行 Select 时)。
发生这种情况时,对 $h.Value
属性的引用已被更改,因为 $h
正在循环。
因此,当计算表达式时,$h
指向最后一个被循环的对象(因此是 hashmap 的最后一个元素)。这是管道中评估的每个 select 语句 的情况。
我可以通过将 $h
的引用(或其值)保存在另一个变量中来解决这个问题。
但是我需要一些硬编码的变量。
我该如何解决这个问题?
感谢PetSerAl,这里是经过测试和工作的代码示例:
foreach ($h in $mapping.GetEnumerator()) {
$selects += @{ L = $h.Name; E = { $_[$h.Value] }.GetNewClosure() }
}
我们可以使用闭包在循环内冻结对 $h
的引用,如 in this article 所述。
预期的脚本输出:我想从 Microsoft SharePoint 列表中导出包含特定列的 CSV 文件。
脚本大纲:
首先,我获取 $items
:
$query = New-Object Microsoft.SharePoint.Client.CamlQuery
$items = $list.GetItems($query)
输出 CSV 文件的列在哈希图中定义 $h
($displayName => $internalName
)。
现在我为每一列创建一个新的 Hashtable 并将其添加到 $selects
:
$selects = @()
foreach ($h in $mapping.GetEnumerator()) {
$selects += @{ L = $h.Name; E = { $_[$h.Value] } }
}
然后我导出 CSV 文件:
$items | Select-Object $selects | Export-Csv -Path $outputPath
现在的问题:
在 E 中,我定义了一个表达式,仅在我需要时才计算它(懒惰地,因此在执行 Select 时)。
发生这种情况时,对 $h.Value
属性的引用已被更改,因为 $h
正在循环。
因此,当计算表达式时,$h
指向最后一个被循环的对象(因此是 hashmap 的最后一个元素)。这是管道中评估的每个 select 语句 的情况。
我可以通过将 $h
的引用(或其值)保存在另一个变量中来解决这个问题。
但是我需要一些硬编码的变量。
我该如何解决这个问题?
感谢PetSerAl,这里是经过测试和工作的代码示例:
foreach ($h in $mapping.GetEnumerator()) {
$selects += @{ L = $h.Name; E = { $_[$h.Value] }.GetNewClosure() }
}
我们可以使用闭包在循环内冻结对 $h
的引用,如 in this article 所述。