Reputation: 4370
I want to create an array that looks like this
{
"requestType": "addUsersToGroups",
"orgToken": "organization_api_key",
"assignedUsers" :
[
[{"name":"group_name"},[{"email":"assigned_user_email"}]]
]
}
But, an extra []
in assignedUsers
is what I'm not able to get. I'm unable to get a list inside list for assignedUsers
. All I'm getting is a list.
This is what I tried:
$assignedUsers = (
(
@{"name" = "group_members_$productName"},
(
@{"email" = $user}
)
)
)
$body= @{
"requestType" = "addUsersToGroups"
"productName" = $productName
"userKey" = $userKey
"orgToken" = $orgToken
"assignedUsers" = $assignedUsers
} | ConvertTo-Json
Write-Output $body
But, the output is
{
"requestType": "addUsersToGroups",
"assignedUsers": [
{
"name": "group_members_NewProduct"
},
{
"email": "my_Email"
}
],
"userKey": "userKey",
"orgToken": "orgToken",
"productName": "NewProduct"
}
Upvotes: 1
Views: 1067
Reputation: 61068
Try building your $assignedusers
and $body
like this:
$orgToken = "organization_api_key"
$userKey = "userkey"
$productName = "NewProduct"
$assignedUsers = ,@(
@{"name" = "group_name"},
@(@{"email" = "assigned_user_email"})
)
$body = [ordered]@{
"requestType" = "addUsersToGroups"
"orgToken" = $orgToken
"productName" = $productName
"userKey" = $userKey
"assignedUsers" = $assignedUsers
}
$body | ConvertTo-Json -Depth 5
Because the ConvertTo-Json
cmdlet creates valid, but rather ugly formatted json, you can make use of the Format-Json
function I posted here some time ago.
With that function in place, just change the last line in the code to
$body | ConvertTo-Json -Depth 5 | Format-Json
to get this result:
{ "requestType": "addUsersToGroups", "orgToken": "organization_api_key", "productName": "NewProduct", "userKey": "userkey", "assignedUsers": [ [ { "name": "group_name" }, [ { "email": "assigned_user_email" } ] ] ] }
Upvotes: 1
Reputation: 338208
Arrays are not created by ()
or @()
. They are created by ,
– the comma operator(*) see below.
As soon as you either separate multiple items with a comma, or prefix a single item with a comma, an array is the result:
$a = 1,2,3 # -> [1,2,3]
$a = ,1 # -> [1]
Note that when the ,
is in the front, it will always (!) produce a single-item array:
$a = ,1,2,3 # -> [[1],2,3]
$a = ,,1 # -> [[1]]
We can use this behavior to create nested single-item arrays:
$assignedUsers = ,(
@{"name" = "group_name"},
,@{"email" = "assigned_user_email"}
)
$body = @{
"assignedUsers" = $assignedUsers
}
$body | ConvertTo-Json -Depth 5 -Compress
# -> {"assignedUsers":[[{"name":"group_name"},[{"email":"assigned_user_email"}]]]}
Note that I've done it again for the email. Also there are no @()
because they are not needed.
(*) In fact, @()
also creates an array. @(1)
will be a single-item array. But in @(1,2)
, what actually creates the array is the comma, whether you additionally wrap it in @()
or not makes no difference, and it's in fact unnecessary.
However, @()
processes its contents. If an item is iterable, @()
will iterate it and merge the results into a new array (that's called "unrolling"):
$a = 1,2,3
$b = 4,5,6
$c = @(
$a # iterable
$b # iterable
) # -> [1,2,3,4,5,6]
That's also why you cannot nest it to create nested arrays. @(@(1,2,3))
is still only [1,2,3]
, because first the inner @()
gets an array, iterates it, and outputs it. Then the outer @()
gets that array, iterates it, you get the picture. These are equivalent:
@{"prop" = 1,2,3} | ConvertTo-Json -Compress # -> {"prop":[1,2,3]}
@{"prop" = (1,2,3)} | ConvertTo-Json -Compress # -> {"prop":[1,2,3]}
@{"prop" = @(1,2,3)} | ConvertTo-Json -Compress # -> {"prop":[1,2,3]}
@{"prop" = @(@(1,2,3))} | ConvertTo-Json -Compress # -> {"prop":[1,2,3]}
The unary ,
on the other hand does nothing of that sort. It simply takes whatever thing there is to the right of it and wraps it in an array.
@{"prop" = 1,2,3} | ConvertTo-Json -Compress # -> {"prop":[1,2,3]}
@{"prop" = ,1,2,3)} | ConvertTo-Json -Compress # -> {"prop":[[1],2,3]}
@{"prop" = ,(1,2,3)} | ConvertTo-Json -Compress # -> {"prop":[[1,2,3]]}
@{"prop" = ,@(1,2,3)} | ConvertTo-Json -Compress # -> {"prop":[[1,2,3]]}
$items = 1,2,3
@{"prop" = $items} | ConvertTo-Json -Compress # -> {"prop":[1,2,3]}
@{"prop" = ,$items} | ConvertTo-Json -Compress # -> {"prop":[[1,2,3]]}
So using @()
is optional, you don't really need it to create arrays. You can use it when you require the "unrolling" behavior, or for the sake of source code formatting, because commas are optional inside of it when you use line-breaks to separate the elements. The results of
@(
"a very long thing"
"another very long thing"
"yet another very long thing"
)
and
"a very long thing","another very long thing","yet another very long thing"
are equivalent, but the former is easier to read. More in-depth information on how @()
works is over here.
Upvotes: 2