Экспорт данных в порядке их добавления - PowerShell Export-Csv - PullRequest
0 голосов
/ 30 июня 2018

У меня есть этот код

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

Как получить экспорт в том порядке, в котором он был добавлен?

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Полезный ответ LotPings предоставляет эффективные решения.

Что касается что вы пытались :

Путем построения только одного [pscustomobject] экземпляра вне цикла :

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

, а затем обновлять только свойства этого экземпляра в каждой итерации цикла:

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

вы эффективно добавляли один и тот же экземпляр [pscustomobject] несколько раз в массив результатов вместо создания отдельного объекта в каждой итерации.

Поскольку один и тот же объект неоднократно обновлялся, этот объект в конечном итоге имел свойства last объекта во входной коллекции, $data.

В сторону:

[PSCustomObject] @() фактически совпадает с @(): [PSCustomObject] игнорируется и вы получаете массив [object[]].

Чтобы ввести массив как экземпляр, содержащий [PSCustomObject] экземпляров, вам нужно будет использовать array -тип-приведение: [PSCustomObject[]] @().

Однако, учитывая, что экземпляры любого типа могут быть преобразованы в [PSCustomObject] - что на самом деле совпадает с [psobject] - это не обеспечивает безопасность типов и не повышает производительность.

Кроме того, поскольку ваша $rec переменная не ограничена по типу (она определяется как $rec = [<type>] ..., а не [<type>] $rec = ...), и вы используете +=, чтобы «добавить» в массив (что неизменно требует создание нового экземпляра за кулисами), $rec вернется к массиву [object[]] после первой операции +=.

0 голосов
/ 30 июня 2018

Даже без использования вашей функции, простой

$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
...