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.
CodePudding user response:
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
CodePudding user response:
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
}