Как трансформировать коллекцию объектов в коллекцию новых объектов другого типа в Powershell? - PullRequest
2 голосов
/ 19 марта 2019

Предположим, у меня есть метод, который получает коллекцию перечислений моего типа enum ProjectName и имеет коллекцию Server объектов, которые я хочу связать с этими ProjectName s в типе с именем Project;как бы я сделал это в Powershell Select-Object (или в другом эквиваленте LINQ Select).

C # -эквивалент того, что я хочу произвести в Powershell, таков:

var servers = new[]
{
    new Server(/*someOtherProjectsCollection goes here*/),
    new Server(/*someOtherProjectsCollection goes here*/),
    new Server(/*someOtherProjectsCollection goes here*/)
};
var projects = GetProjectNames().Select(projectName => new Project(projectName, servers.Where(server => server.Projects.Any(serverProject => serverProject.Name == projectName))));

Но у меня есть следующее:

$servers = [Server]::new(/*someOtherProjectsCollection goes here*/), [Server]::new(/*someOtherProjectsCollection goes here*/), [Server]::new(/*someOtherProjectsCollection goes here*/)

$projects = (GetProjectNames()) | Select-Object {
    $selectedProjectName = $_

    return [Project]::new($_, ($servers | Where-Object { $_.projects.Where({ $_ -eq $selectedProjectName }).Count -gt 0 }))
}

Когда я пытаюсь прочитать $projects в Powershell LSE (находясь в точке останова после этой последней строки), он просто возвращает код в виде строки иЯ даже не могу привести его к [Project[]].Я думаю, что проблема может заключаться в использовании фигурных скобок с Select-Object, но я не уверен, как еще создать новый объект Project в Select-Object.

1 Ответ

2 голосов
/ 19 марта 2019

Вы хотите, чтобы ForEach-Object вместо Select-Object возвращало новый [Project] экземпляр для каждого имени проекта; Кроме того, ваш код может быть оптимизирован:

$projects = GetProjectNames | ForEach-Object {
    $projectName = $_
    [Project]::new(
      $_, 
      $servers.Where({ $_.projects -eq $projectName })
    )
}
  • Select-Object - для создания новых пользовательских объектов на основе выбранных свойств из входных объектов; напротив, вы создаете новый, конкретный экземпляр типа из каждого входного объекта, что должно быть сделано в вызове ForEach-Object, где вы явно управляете выводом.

  • $_.projects -eq $projectName в качестве условия полагается на способность PowerShell использовать -eq с массивом в качестве LHS, в этом случае выполняется фильтрация и фильтруется subarray возвращается; поскольку .Where() интерпретирует вывод блока скрипта как Boolean , пустой подмассив интерпретируется как $false, тогда как один с хотя бы одним элементом интерпретируется как $true.

  • Также обратите внимание, что вам не нужен явный return, учитывая поведение неявного вывода PowerShell: поскольку только что созданный экземпляр [Project] не назначен переменной или не отправлен в другое место , он автоматически возвращается.

...