Reputation: 3521
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,,
.
Upvotes: 1
Views: 133
Reputation: 437833
If you really want to stick with this parameter format, you can create the desired output array as follows:
$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'
$i = 0
$array = @(foreach ($role in $roles) {
, ($role, $members[$i++])
})
Note that if you pass your arguments from PowerShell, you need to quote them, as PowerShell will otherwise parse them as an array.
And with quoting you're free to use ;
in lieu of ,,
, for instance, to separate the member groups.
A better way to represent the argument data for later processing is to create an array of custom objects rather than a nested array:
$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'
$i = 0
$array = @(foreach ($role in $roles) {
[pscustomobject] @{
Role = $role
Members = $members[$i++] -split ','
}
})
Each object in $array
now has a .Role
and a .Members
property, the latter containing the individual members as a an array of strings.
Alternatively, you could create a[n ordered] hashtable from the input, keyed by role name, but that is only necessary if you need to access roles by name or if you wanted to rule out duplicate roles having been specified.
Here's an alternative argument format that is easier to understand:
$rolesAndMembers = 'role1 = member1,member2 ; role2= ; role3=member3 ; role4=member4'
$array = @(foreach ($roleAndMembers in ($rolesAndMembers -replace ' ' -split ';')) {
$role, $members = $roleAndMembers -split '='
[pscustomobject] @{
Role = $role
Members = $members -split ','
}
})
Upvotes: 2
Reputation: 174485
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
}
Upvotes: 1
Reputation: 24555
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).
Upvotes: 2