Сгруппировать два массива объектов в powershell - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть два массива объектов. Я хочу вставить соответствующий extraProperty в массив "car", если он найден. Может быть несколько дополнительных свойств или их нет. То есть, я хотел бы добавить, когда для соответствующего автомобиля был найден extraProperty, массив со списком найденных дополнительных свойств.

Каждый extraProperties состоит из объекта со следующими свойствами: Id, Name, Value.

Код:

param(
    [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$false)]
    [string]$Types,
    [Parameter(Mandatory=$false, Position=2, ValueFromPipeline=$false)]
    [string]$PathFile,
    [Parameter(Mandatory=$false, Position=3, ValueFromPipeline=$false)]
    [string]$PathPropertyFile 
)
    $profiles_list = Import-Csv $PathFile -Header Id, model, Type Delimiter ";" 
    $extraProperties_list = Import-Csv $PathPropertyFile -Header ProfileId,Name,Value -Delimiter ";" # Get-Content -Path $pathFile  
        foreach($p in $car_list) {
                $Property =  $property_list.Where({$_.Id -eq $p.Id}) | Select-Object -Property Name,Value
                if(-Not (($null -eq $Property ) -And (@($Property ).Count -eq 0)) ) {
                    $p = $p | Add-Member -NotePropertyMembers @{Properties=$Property }
                } else {
                    $p = $p | Add-Member -NotePropertyMembers @{Properties=@()}
                }
        }

Образец данных:

PropertyFile.csv

Id     | Name     | Value
504953 | Example1 | Value1
504953 | Example2 | Value2
504955 | Example3 | Value3

CarFiles.csv

Id     | Model  | Type 
504953 | Model1 | 3
504954 | Model1 | 0
504955 | Model3 | 3

Проблема в том, что код не эффективен. Массив car достигает 200000 позиций, и где каждая позиция является объектом с несколькими свойствами, а массив свойств также достигает этих значений. Выполнение сценария занимает бесконечные часы.

Есть ли способ оптимизировать вставку нового свойства в массивы?

1 Ответ

0 голосов
/ 20 апреля 2020

Вам нужно проверить, быстрее ли это (мы не знаем, насколько велики CSV-файлы), но вы можете сделать это так:

Для демонстрации я использую Here-Strings, но в реальной жизни вы импортируете данные из файлов:

$profiles_list = Import-Csv $PathFile -Delimiter ";" 
$extraProperties_list = Import-Csv $PathPropertyFile -Delimiter ";"

Используя ваши примеры:

$profiles_list = @"
Id;Model;Type
504953;Model1;3
504954;Model1;0
504955;Model3;3
"@ | ConvertFrom-Csv -Delimiter ';'

$extraProperties_list = @"
Id;Name;Value
504953;Example1;Value1
504953;Example2;Value2
504955;Example3;Value3
"@ | ConvertFrom-Csv -Delimiter ';'

# get the headers from the Cars
$profileHeaders = $profiles_list[0].PsObject.Properties.Name
# get the new property names from the ExtraProperties Name column
$newHeaders = $extraProperties_list.Name | Where-Object {$profileHeaders -notcontains $_}  | Select-Object -Unique

# add all these new properties to the $profiles_list, for now with $null values
$profiles_list | ForEach-Object {
    foreach($prop in $newHeaders) {
        $_ | Add-Member -MemberType NoteProperty -Name $prop -Value $null
    }
}

# group the $extraProperties_list by the Id column and loop through these groups
$extraProperties_list | Group-Object Id | ForEach-Object {
    $id = $_.Name
    # get an array of profiles with matching Ids
    $profiles = $profiles_list | Where-Object {$_.Id -eq $id}
    # and fill in the blanks
    foreach($item in $profiles) {
        foreach($extra in $_.Group) {
            $item.($extra.Name) = $extra.Value
        }
    }
}

# output on screen
$profiles_list

# output to new CSV file
$profiles_list | Export-Csv -Path 'X:\CompletedProfiles.csv' -Delimiter ';' -NoTypeInformation

Результат на экране:

Id       : 504953
Model    : Model1
Type     : 3
Example1 : Value1
Example2 : Value2
Example3 : 

Id       : 504954
Model    : Model1
Type     : 0
Example1 : 
Example2 : 
Example3 : 

Id       : 504955
Model    : Model3
Type     : 3
Example1 : 
Example2 : 
Example3 : Value3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...