1

我有这个代码

function get-data()
{
   $rec=[PSCustomObject]@()
   $DLGP = "" | Select "Name","Grade","Score"

   foreach($record in $data) 
   {
       $DLGP.Name=$record.name
       $DLGP.Grade=$record.grade
       $DLGP.Score=$record.score
       $rec += $DLGP
   }
   return $rec
}

$mydata=get-data
$mydata | Export-Csv -Path $outputPath -NoTypeInformation

问题是,数据没有按照我添加到 $rec 的顺序导出

如何按添加顺序导出它?

4

2 回答 2

3

甚至不使用您的功能,一个简单的

$mydata = $data | select Name,Grade,Score

会产生预期的结果。

您的功能在 IMO 过于复杂:

$Data = @"
Name,Grade,Score,Dummy
Anthoni,A,10,v
Brandon,B,20,x
Christian,C,30,y
David,D,40,z
"@ | ConvertFrom-Csv

function get-data() {
   ForEach($record in $data) {
       [PSCustomObject]@{
           Name =$record.name
           Grade=$record.grade
           Score=$record.score
       }
   }
}

$mydata=get-data
$mydata # | Export-Csv -Path $outputPath -NoTypeInformation

在这里返回几乎相同的顺序:

Name      Grade Score
----      ----- -----
Anthoni   A     10
Brandon   B     20
Christian C     30
David     D     40
于 2018-06-30T07:16:02.300 回答
2

LotPings 的有用答案提供了有效的解决方案。

至于你尝试了什么:

通过在循环外仅构造一个 [pscustomobject]实例:

$DLGP = "" | Select "Name","Grade","Score"

然后在每次循环迭代中只更新一个实例的属性:

$DLGP.Name=$record.name
# ....

有效地将相同的[pscustomobject]实例多次添加到结果数组中,而不是在每次迭代中创建一个不同的对象。

由于同一对象被重复更新,该对象最终具有输入集合中最后一个$data对象的属性, .

作为旁白:

[PSCustomObject] @()实际上等同于@():[PSCustomObject]忽略并且你得到一个[object[]]数组。

要将数组键入为包含[PSCustomObject]实例的数组,您必须使用数组类型的强制转换:[PSCustomObject[]] @()

但是,鉴于可以强制转换任何类型的实例[PSCustomObject]——这实际上是相同的[psobject]——这没有提供类型安全和性能优势。

此外,由于您的$rec变量不受类型约束(它被定义为$rec = [<type>] ...而不是[<type>] $rec = ...)并且您+=用于“添加到”数组(这总是需要在幕后创建一个新实例$rec),因此将恢复为[object[]]数组第一次+=手术后。

于 2018-07-01T00:43:19.317 回答