'How to combine string inputs and generate array dynamically?

param([string]$roles,[string]$members)

Suppose I am passing input on the command line like this:

PS> role1,role2,role3,role4 member1,member2,,,,member3,,member4

The array I expect for this would be:

$array = @(
    @('role1', 'member1,member2'),
    @('role2', ''),
    @('role3', 'member3'),
    @('role4', 'member4')
)

I know to turn string to array:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

Now how do I combine $roles with $members so that each role will be associated with member(s)? and how wouldIi generate the array dynamically?

Pseudocode:

$array = @()

($roles+$members) | %{
    $role = $_.roles
    if ($_.members) {
        $_.members -split ',,' | ForEach-Object { $array += $role $_ }
    } else {
        $array += $role 
    }
}

Note: I am splitting members as an index of its own for each double comma because apparently semicolons aren't accepted on a command line because they break the command line, so I have to use double comma as delimiter.

Note 2: notice the 4 commas: ,,,, this indicates that role2 does not have members to add, so in essence it means between the 4 commas is no input for member to that index/item (role2), i.e. ,,EMPTY,,.



Solution 1:[1]

Your parameter format is rather bizarre, but here's one way:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

$result = @()
for ( $i = 0; $i -lt $roles.Count; $i++ ) {
  $result += ,@($roles[$i],$members[$i])
}

I would recommend redesigning the script to use standard PowerShell parameters (the engineering effort would be worth it, IMO).

Solution 2:[2]

I'd strongly recommend using hashtables/dictionaries to pass these role mappings:

param(
    [System.Collections.IDictionary]$RoleMembers
)

# now we can access each mapping by role name:
$RoleMembers['role1'] # member1, member2

# or iterate over them like an array:
foreach($role in $RoleMembers.Keys){
    $RoleMembers[$role]
}

You could use one of the construct the input argument from your current input strings:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ','

$roleMembers = @{}

for ($i = 0; $i -lt $roles.Count; $i++) {
  # `Where Length -ne 0` to filter out empty strings
  $roleMembers[$roles[$i]] = $members[($i*2)..($i*2+1)] |Where Length -ne 0
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Mathias R. Jessen