1

How can I print a JSON output with sorted array of objects? My $result object must remain as it is, the order of "Good" or "Bad" doesn't matter, I'm trying to sort the objects in the arrays sorted by "count" property in ascending order.

My code:

$result = [PSCustomObject]@{
    Good = @() 
    Bad  = @()
}

$food = [PSCustomObject]@{
    name  = "Banana"
    count = 2
}

if ($food.count -gt 3) { $result.Good += $food }
else { $result.Bad += $food }

$sortGood = $result.Good | Sort-Object count
$sortBad = $result.Bad | Sort-Object count
Write-Output ($result | ConvertTo-Json)

My JSON output is:

{
    "Good": [
                {
                    "name": "Apple"
                    "count": 10
                },
                {
                    "name": "Lime"
                    "count": 5
                },
                {
                    "name": "Peach"
                    "count": 7
                }
            ],
    "Bad": [
                {
                    "name": "Banana"
                    "count": 2
                },
                {
                    "name": "Kiwi"
                    "count": 1
                },
                {
                    "name": "Orange"
                    "count": 3
                }
            ] 
}

How can I print a JSON that looks like this? (fruits sorted by "count" property in ascending order)

{
    "Good": [
                {
                    "name": "Lime"
                    "count": 5
                },
                {
                    "name": "Peach"
                    "count": 7
                },
                {
                    "name": "Apple"
                    "count": 10
                },
            ],
    "Bad": [
                {
                    "name": "Kiwi"
                    "count": 1
                },
                {
                    "name": "Banana"
                    "count": 2
                },
                {
                    "name": "Orange"
                    "count": 3
                }
            ] 
}

[Problem fixed] Edited solution:

$result.Good = $result.Good | Sort-Object count
$result.Bad  = $result.Bad | Sort-Object count
Write-Output ($result | ConvertTo-Json)
Adela
  • 23
  • 4

3 Answers3

2

Sort-Object does not "sort the object". It returns a sorted copy of the object. So this

$sortGood = $result.Good | Sort-Object count

will result in $sortGood being sorted properly, and $result.Good being exactly as it was.

$json = @"
{
    "Good": [
        {"name": "Apple", "count": 10},
        {"name": "Lime", "count": 5},
        {"name": "Peach", "count": 7}
    ],
    "Bad": [
        {"name": "Kiwi", "count": 1},
        {"name": "Orange", "count": 4}
    ] 
}
"@

$data = ConvertFrom-Json $json

$food = @{
    name  = "Banana"
    count = 2
}

if ($food.count -gt 3) {
    $data.Good += $food
} else {
    $data.Bad += $food
}

$data.Good = $data.Good | Sort-Object count
$data.Bad = $data.Bad | Sort-Object count

$result = $data | ConvertTo-Json -Depth 10
$result

gives

{
    "Good":  [
                 {
                     "name":  "Lime",
                     "count":  5
                 },
                 {
                     "name":  "Peach",
                     "count":  7
                 },
                 {
                     "name":  "Apple",
                     "count":  10
                 }
             ],
    "Bad":  [
                {
                    "name":  "Kiwi",
                    "count":  1
                },
                {
                    "count":  2,
                    "name":  "Banana"
                },
                {
                    "name":  "Orange",
                    "count":  4
                }
            ]
}

Note that I'm always re-assigning the values of $data.Good and $data.Bad:

  • Using $data.Good += $food creates a new array (!) with $food at the end, and then assigns that to $data.Good. (It's shorthand for $data.Good = $data.Good + $food.)
  • Using $data.Good = $data.Good | Sort-Object count creates a new array (!) in a different order, and then assigns that to $data.Good.
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Thank you, problem was fixed (see edit), why did you use "-Depth 10"? – Adela Oct 24 '21 at 10:07
  • @Adela To make you aware of the `-Depth` parameter. By default, PowerShell only converts nested data up to 2 levels deep to JSON. Any more nesting than that, and you need to specify explicitly how many levels you want. 10 seems a more reasonable value to me. – Tomalak Oct 24 '21 at 11:32
  • @Adela Also, instead of including the solution into your question, mark the answer that got you into the right direction as accepted. – Tomalak Oct 24 '21 at 11:33
0

Hey there I guess you forgot to add -Property after Sort-Object i.e

$sortGood = $result.Good | Sort-Object -Property count

Give it a try and let me know !!!

sammyhp
  • 122
  • 3
  • Adding `-Property` is actually not necessary. `Sort-Object` will assume that you mean `-Property` when you just give a name. `Sort-Object count` is fine. – Tomalak Oct 24 '21 at 09:05
0

I would do it like this:

ConvertTo-Json @{
    Good = $result.Good | sort Count
    Bad = $result.Bad | sort Count
}
marsze
  • 15,079
  • 5
  • 45
  • 61