0

I have several lists consisting of strings like this (imagine them as a tree of sort):

$list1:

data-pool
data-pool.house 1
data-pool.house 1.door2
data-pool.house 1.door3
data-pool.house2
data-pool.house2.door 1

To make them more easier to parse as a tree how can indent them based on how many . characters occur while ditching the repetitive text earlier in the line? For example:

data-pool
  house 1
    door2
    door3
  house2
    door 1

The way I approached it counting the occurrences of .s with .split('.').Length-1 to determine the amount of needed indents and then adding the spaces using .IndexOf('.') and .Substring(0, <position>) feels overly complicated - or then I just can't wrap my head around how to do it in a less complicated way.

6
  • Your solution seems fine to me? Commented Dec 1, 2021 at 15:51
  • Is the number of child nodes always between 1 and 2? Commented Dec 1, 2021 at 16:55
  • @ITM: It could be, but going through hundreds - thousands of lines seems heavy. Commented Dec 1, 2021 at 18:59
  • @SantiagoSquarzon: No, the text can vary a lot and be almost anything. Commented Dec 1, 2021 at 19:00
  • What I meant on my previous comment was, is it possible to have something like this: data-pool.house 1.door1.something.something.something.? Or will there always be 1 door and 1 house? Commented Dec 1, 2021 at 19:26

2 Answers 2

1

I think this should work as long as the number of nodes from line to line are ordered, what I mean by this is that it will not look "pretty" if for example the current node has n elements and the next node has n+2 or more.

To put it into perspective, using this list as an example:

$list = @'
data-pool
data-pool.house 1
data-pool.house 1.door2
data-pool.house 1.door3
data-pool.house 1.door4.something1
data-pool.house2
data-pool.house2.door 1
data-pool.house2.door 2.something1
data-pool.house2.door 3.something1.something2
data-pool.house3
data-pool.house3.door 1
data-pool.house3.door 2
'@ -split '\r?\n'

The function indent will take each line of your list and will split it using . as delimiter, if the count of elements after splitting is lower than or equal to 1 it will not perform any modification and display that line as is, else, it will multiply the $IndentType containing 2 white spaces by the number of elements of the split array minus 1 and concatenate it with the last element of the split array.

function indent {
param(
    [string]$Value,
    [string]$IndentType = '  '
)
    $out = $Value -split '\.'
    $level = $out.Count - 1

    '{0}{1}' -f ($null,($IndentType*$level))[[int]($out.Count -gt 1)], $out[-1]
}

$list.ForEach({ indent $_ })

Sample:

data-pool
  house 1
    door2
    door3
      something1
  house2
    door 1
      something1
        something2
  house3
    door 1
    door 2
Sign up to request clarification or add additional context in comments.

3 Comments

This works as expected, thank you! The lines are sorted & ordered before this function takes place so the nodes and elements are properly kept in place.
@lapingultah thats good to know, and happy to help.
@lapingultah not sure i'm following, could you ask a new question explaining in detail this new requirement ?
0

the approach to get the last element of the string is below

## String
$string = "data-pool.house 1"
## split the string into an array every "."
$split = $string.split(".")
## return the last element of the array
write-host $split[-1] -ForegroundColor Green

Then to test against each string

$myArray = ("data-pool", "data-pool.house 1", "data-pool.house 1.door2", "data-pool.house 1.door3", "data-pool.house2", "data-pool.house2.door 1")
ForEach($Name in $myArray) {
    ## String
    $Name = $Name.ToString()
    $string = $Name
    $split = $string.split(".")
    ## return the last element of the array
    write-host $split[-1] -ForegroundColor Green
}

2 Comments

I don't understend the logic in this. $myArray here is already cast as String so .ToString() is not needed and $string = $Name could be omitted using only $split = $Name.split(".") instead. Also this doesn't count the needed indents.
Since I do not have exchange to build the array. I used what you provided to demonstrate, what you need to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.