'Powershell decimal to [Int] not failing
I am trying to validate a string of what should be comma separated integer values to use as success codes. If I start with an array with some invalid values, like this...
$test = @(0, 100, -200, 3.3, 'string')
foreach ($item in $test) {
if ($item -isnot [Int]) {
Write-Host "![Int] $item"
} else {
Write-Host "[Int] $item"
}
}
I get the expected results, the first three are [Int]
and the last two are not.
However, if I start from a string and build the array, like this
$testString = '0, 100, -200, 3.3, string'
$test = $testString.Split(',').Trim()
then all tests are not [Int]
, which makes sense because the array will be strings. I need to cast to [Int]
first. But when I do, like this
$testString = '0, 100, -200, 3.3, string'
$test = $testString.Split(',').Trim()
foreach ($item in $test) {
if ($item -as [Int] -isnot [Int]) {
Write-Host "![Int] $item"
} else {
Write-Host "[Int] $item"
}
}
3.3 is returning as [Int]
. I found this which clues me in that casting is too smart for what I am trying to do it seems. So, IS there a way to cast a decimal to int and get a failure, or do I need two conditionals, one to cast and catch the true strings, and one to look for .
and thus find the decimals? Or perhaps to compare the value of [Int]
with a cast to [Single]
like this?
$testString = '0, 100, -200, 3.3, string'
$test = $testString.Split(',').Trim()
foreach ($item in $test) {
if ($item -as [Int32] -isnot [Int32]) {
Write-Host "![Int] $item"
} else {
Write-Host "[Int] $item"
}
}
This is the most elegant way I have managed to get to work, but I wonder if there is actually a better approach?
I also tried if ([Int]$item -isnot [Int]) {
, which is I think an actual Cast, while -as
is technically Coercion, and that still fails to catch the decimal, while throwing an error on the string. So I am left thinking I understand Casting vs Coercion better than I did, and the working code above is as good as it gets. Hoping for some verification or refutation on both.
EDIT: Actually, that only works because my decimal is not .0
. If I want to flag 3.0
as an error as well as 3.3
I really need to check for the decimal instead, like so.
if (($item -as [Int] -isnot [Int]) -or ($item -like '*.*')) {
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|