Creating nested data structure

Hi all

I have a string like ‘A/B/C’ that I’m trying to get into a nested structure like the following:

I thought this would be pretty straightforward using recursion, but only the top-level hashtable (“A”) gets added to $bar…


Any ideas? Must be some issue with passing by ref the deeper array?

Note I have an array of strings like ‘A/B/C’ (e.g. ‘A/B/D’, 'D/E/F) to add to the structure, but that should be easy once I get past this first issue…

Here is one way, build it backwards:

$arr = 'A','B','C','D','E','F','G'
[array]::Reverse($arr)

$lastObj = $null
foreach ($item in $arr) {
    $lastObj = [pscustomobject]@{
        Name    = $item
        Folders = @($lastObj)
    }
}

$lastObj | ConvertTo-Json -Depth 30

Wow this was a fun exercise. Haven’t messed with recursion much since my freshman year at college. I created a recursive function that will create the data structure you want.

function folders([System.Collections.ArrayList]$Name, $ht = @{}) {
    $ht.name = $Name[0]
    if ($Name.count -eq 1) {$ht.folders = @(); $ht} #base case
    else {
        $Name.RemoveAt(0)
        $ht.folders = @(folders -ht $ht.Clone() -Name $Name)
        $ht #recurse case
    } #else
} #function

$TestData = @("A/B/C","D/E/F")
$Result = $TestData | ForEach-Object {folders -Name @($_ -split "/")}

 

I like using a Stack object for this exercise:

$folders = 'a/b/c','d/e/f' | Foreach-Object {
    [system.collections.stack]$stack = $_ -split '/' | Foreach-Object {
        [ordered]@{name = $_; folders = @()}
    }
    while ($stack.Count -gt 1) {
        $stack.ToArray()[1].Folders = ,$stack.Pop()
    }
    $stack
}
Remove-Variable stack