Reputation: 3
General task: I need to replace numbers in an array and build /replace a string based on a matrix.
In detail: I have an array with two columns, user and ID (=Describtion). From the second column, I need to take the ID, divide it into two pieces, replace the numbers by characters, rebuild a string out of those two parts and put it back into the first array.
Like something:
$Users = Get-some-content()
$Users
User ID (Describtion)
-------------- -----------
User1 12345678
User2 87654321
$UsersFirstPart = @($Users.Description)
$UsersFirstPart = @($UsersFirstPart.substring(0,4))
$UsersSecondPart = @($Users.Description)
$UsersSecondPart = @($UsersSecondPart.substring(4,4))
$UsersFirstPart = $UsersFirstPart | ForEach-Object { $_.replace("0","A").replace("1","B").replace("3","C")}
$UsersSecondPart = $UsersSecondPart| ForEach-Object { $_.replace("0","Z").replace("1","X").replace("3","Y")}
### Then I need to build the string together like ###
$UserNew = $UserFristPart + “.” + $UserSecondPart
Then I need to exchange the NewUserIDs with the original ones. At the end, it should look like:
User ID
-------------- -----------
User1 AB.CD
User2 DE.FG
Any help is much appreciated!
Upvotes: 0
Views: 1333
Reputation: 7087
I agree with @Theo's comments the question could be more clear. I don't understand where $User.Desription
comes from, since it's not in the columns. Based on your description I'm going to ignore that.
I came up with the following demo:
# Build some sample data:
$Objects =
@(
[PSCustomObject]@{
User = 'MrJones'
ID = 1234
}
[PSCustomObject]@{
User = 'MrsHowel'
ID = 5678
}
[PSCustomObject]@{
User = 'MrSmith'
ID = 9012
}
)
$Objects |
ForEach-Object{
$FirstPart = ([char[]]$_.ID.ToString().SubString(0,2))
$FirstPart = $FirstPart.ForEach( { [Char](65 + [String]$_) } )
$SecondPart = ([char[]]$_.ID.ToString().SubString(2))
$SecondPart = $SecondPart.ForEach( { [Char](65 + [String]$_) } )
$_.ID = ($FirstPart -join '') + '.' + ($SecondPart -join '')
}
$Objects
Output:
User ID
---- --
MrJones BC.DE
MrsHowel FG.HI
MrSmith JA.BC
There's a little complexity in some of the casting and working with PowerShells underlying type conversion system. However, this basically maps the digits in the ID to an ASCII charter code using simple arithmetic. For example "A" is [Char]65
then [Char](0+65)
is "A". So assuming the replacement map progresses as described this should do it.
I could've looped the other way looking for each character code, but at a glance I felt like that would be less efficient. So I started with this approach.
Update:
Considering the question hasn't been updated with a map of numbers to characters, I asked myself what if it were. After all there are only 10 digits so this should be pretty easy to demonstrate. So assuming the previous answer wasn't accurate meaning you can't rely on the ASCII character code here's another approach that would be easy to adjust regardless.
$ResolveNumberToLetter =
@{
0 = 'A'; 1 = 'B'; 2 = 'C'; 3 = 'D'
4 = 'E'; 5 = 'F'; 6 = 'G'; 7 = 'H'
8 = 'I'; 9 = 'J'
}
$Objects =
@(
[PSCustomObject]@{
User = 'MrJones'
ID = 1234
}
[PSCustomObject]@{
User = 'MrsHowel'
ID = 5678
}
[PSCustomObject]@{
User = 'MrSmith'
ID = 9012
}
)
$Objects |
ForEach-Object{
$FirstPart = ([char[]]$_.ID.ToString().SubString(0,2))
$FirstPart = $FirstPart.ForEach( { $ResolveNumberToLetter[ [Int][String]$_ ] } )
$SecondPart = ([char[]]$_.ID.ToString().SubString(2))
$SecondPart = $SecondPart.ForEach( { $ResolveNumberToLetter[ [Int][String]$_ ] } )
$_.ID = ($FirstPart -join '') + '.' + ($SecondPart -join '')
}
This example uses a hash table to store and later resolve the relationship between digits and letters. Then in the loop instead of figuring out the relative ASCII character code just look up the value from the hash table.
This example does have the same casting difficulties so I wanted to explain that a bit. Something like [Char]"0"
will return 48 which is the character code for "0", and you can't look up 48 in our new table, nor can you perform the appropriate math as we had in the previous example. However, if you cast a string "0" to an [int]
you will indeed get 0. In short converting to a string before converting to int resolves the issue.
Note: I may work on a 3rd example to side step the [int][char] example. Will update further if successful.
Upvotes: 1