Вы можете объединить Select-Object -ExpandProperty
с общим параметром -PipelineVariable
и клонированием (синтаксис PSv3 +):
Для входных коллекций экземпляров [pscustomobject]
или [hashtable]
:
# Sample input array of custom objects to expand by .RecordDate
$array =
[pscustomobject] @{ RecordDate = 1, 2; OtherProp1 = 'one'; OtherProp2 = 'two' },
[pscustomobject] @{ RecordDate = 3, 4; OtherProp1 = 'three'; OtherProp2 = 'four' }
# Write the array elements to the pipeline, and store each in variable
# $objectOrHashtable for use in a later pipeline segment.
Write-Output $array -PipelineVariable objectOrHashtable |
# Expand the input object's .RecordData property, i.e. send its
# elements one by one to the next pipeline segment.
Select-Object -ExpandProperty RecordDate |
ForEach-Object {
# Clone the original input object.
$clone = if ($objectOrHashtable -is [Management.Automation.PSCustomObject]) {
$objectOrHashtable.psobject.Copy()
} else { # assume [hashtable] or a type that implements [System.ICloneable]
$objectOrHashtable.Clone()
}
# Assign the record date at hand to the clone...
$clone.RecordDate = $_
# ... and output it.
$clone
}
Вышесказанное дает следующее;обратите внимание, что было выведено 4 объекта на основе перечисления элементов массива .RecordDate
входных объектов при сохранении всех других свойств:
RecordDate OtherProp1 OtherProp2
---------- ---------- ----------
1 one two
2 one two
3 three four
4 three four
Примечание:
Вышеприведенное работает с двумя типами входных объектов:
пользовательских объектов ([pscustomobject]
экземпляров, таких как созданные Import-Csv
)
- Примечание: по техническим причинам вы не можете использовать
-is [pscustomobject]
и вместо этого должны использовать полное имя типа System.Management.Automation.PSCustomObject
(префикс System.
может быть опущен);[pscustomobject]
по историческим причинам совпадает с [psobject]
(System.Management.Automation.PSObject
), а -is [psobject]
также верно для объектов, которые не являются пользовательскими объектами.
хеш-таблицы (System.Collections.Hashtable
экземпляров - но не [ordered]
хеш-таблицы);в более общем смысле, любой тип, который реализует System.ICloneable
.
Клонирование, которое выполняется на пользовательских объектах и хэш-таблице, составляет shallow (member-мудро), но со скалярными строковыми и числовыми значениями, которые являются достаточными.
- Как правило, интерфейс
ICloneable
не предписывает особенности поведения клонирования, поэтому его использование обычно не рекомендуется.
Для входных коллекций [System.Data.DataRow]
экземпляров:
Клонирование коллекции System.Data.DataRow
экземпляров - строк таблицы данных, System.Data.DataTable
- требуется пользовательская логика клонирования , но подход и структура выходных данных в основном одинаковы:
# Create a sample DataTable...
$dt = [System.Data.DataTable]::new('sample')
# ... define the columns ...
$dt.Columns.AddRange([System.Data.DataColumn[]] (
@{ ColumnName = 'RecordDate'; DataType = [object[]] },
@{ ColumnName = 'OtherProp1'; DataType = [string] },
@{ ColumnName = 'OtherProp2'; DataType = [string] }
))
# ...and add sample rows.
@{ RecordDate = 1, 2; OtherProp1 = 'one'; OtherProp2 = 'two' },
@{ RecordDate = 3, 4; OtherProp1 = 'three'; OtherProp2 = 'four' } | % {
$dt.Rows.Add(($dr = $dt.NewRow()))
foreach ($entry in $_.GetEnumerator()) {
$dr[$entry.Key] = $entry.Value
}
}
# Create an auxiliary, empty clone of the input data table
# to facilitate cloning of individual rows.
$dtAux = $dt.Clone()
# Write the data rows to the pipeline, and store each in variable
# $obj for use in a later pipeline segment.
Write-Output $dt.Rows -PipelineVariable row |
# Expand the input object's .RecordData property, i.e. send its
# elements one by one to the next pipeline segment.
Select-Object -ExpandProperty RecordDate |
ForEach-Object {
# Clone the data row at hand.
$dtAux.Clear(); $dtAux.ImportRow($row)
$clone = $dtAux.Rows[0]
# Assign the record date at hand to the clone...
$clone.RecordDate = @($_)
# ... and output it.
$clone
}