After experiencing a lot of down time, We decided to move this site to
CrystalTech.com. CrystalTech.com is powered by only the finest Windows servers providing the best performance, reliability, and value anywhere.
What's the most efficient way to compare two "dotted" numbers?
|
Author |
Message
|
turranx
-
Total Posts
:
59
- Scores: 0
-
Reward points
:
0
- Joined: 2/7/2006
- Location: Cincinnati, OH
-
Status: offline
|
What's the most efficient way to compare two "dotted" numbers?
Sunday, September 20, 2009 11:24 PM
( permalink)
Say you have two product version numbers that use this format: #.##.####.#### . - How would you compare them to see which one is greater/newer?
- Furthermore, what if you couldn't count on this dotted number format to always have four sections?
- And also could not count upon each section to have a predictable number of digits in it?
My solution is below. It works for all three requirements; but is there a more elegant/simpler method to do the same? Can my code be simplified? Function Test-DotNotation {
Param ( $NumberLeft = "",
$Test = "",
$NumberRight = "" )
If (($NumberLeft -eq "") `
-or ($Test -eq "") `
-or ($NumberRight -eq ""))
{ Return -1; }
# Manipulate $NumberLeft and $NumberRight into a type that can be
# used internally within this function with ease
$SegmentCountLeft = ([string]$NumberLeft).Split(".").count;
$SegmentCountRight = ([string]$NumberRight).Split(".").count;
if ($SegmentCountLeft -gt $SegmentCountRight) {$CounterMax = $SegmentCountLeft;}
else {$CounterMax = $SegmentCountRight;}
$StringLeft = "";
$StringRight = "";
For ($Counter = 0; $Counter -lt $CounterMax; $Counter++) {
Switch ($true)
{
($Counter -eq 0) {
$StringLeft += ([string]$NumberLeft).Split(".")[$Counter];
$StringRight += ([string]$NumberRight).Split(".")[$Counter];
}
($Counter -ge $SegmentCountLeft) {
$StringLeft += ("0" * ([string]$NumberRight).Split(".")[$Counter].length);
$StringRight += ([string]$NumberRight).Split(".")[$Counter];
}
($Counter -ge $SegmentCountRight) {
$StringLeft += ([string]$NumberLeft).Split(".")[$Counter];
$StringRight += ("0" * ([string]$NumberLeft).Split(".")[$Counter].length);
}
default {
if ((([string]$NumberLeft).Split(".")[$Counter].length) `
-gt (([string]$NumberRight).Split(".")[$Counter].length)) {
$StringLeft += ([string]$NumberLeft).Split(".")[$Counter];
$StringRight += ("0" * (([string]$NumberLeft).Split(".")[$Counter].length - ([string]$NumberRight).Split(".")[$Counter].length));
$StringRight += ([string]$NumberRight).Split(".")[$Counter];
}
else {
$StringLeft += ("0" * (([string]$NumberRight).Split(".")[$Counter].length - ([string]$NumberLeft).Split(".")[$Counter].length));
$StringLeft += ([string]$NumberLeft).Split(".")[$Counter];
$StringRight += ([string]$NumberRight).Split(".")[$Counter];
}
}
}
}
$NumberLeft = [System.Double]$StringLeft;
$NumberRight = [System.Double]$StringRight;
Switch ($Test)
{
"=" {Return $NumberLeft -eq $NumberRight}
"-eq" {Return $NumberLeft -eq $NumberRight}
">" {Return $NumberLeft -gt $NumberRight}
"-gt" {Return $NumberLeft -gt $NumberRight}
"<" {Return $NumberLeft -lt $NumberRight}
"-lt" {Return $NumberLeft -lt $NumberRight}
"<=" {Return $NumberLeft -le $NumberRight}
"=<" {Return $NumberLeft -le $NumberRight}
"-le" {Return $NumberLeft -le $NumberRight}
">=" {Return $NumberLeft -ge $NumberRight}
"=>" {Return $NumberLeft -ge $NumberRight}
"-ge" {Return $NumberLeft -ge $NumberRight}
default { Return -1; }
}
} Running my code: cls
$NumberOne = "1.1.10.0";
$NumberTwo = "0.240.1.3"
Write-Host "Equals";
Test-DotNotation $NumberOne "=" $NumberTwo;
Test-DotNotation $NumberOne "-eq" $NumberTwo;
Write-Host "`nLess Than";
Test-DotNotation $NumberOne "<" $NumberTwo;
Test-DotNotation $NumberOne "-lt" $NumberTwo;
Write-Host "`nGreater Than";
Test-DotNotation $NumberOne ">" $NumberTwo;
Test-DotNotation $NumberOne "-gt" $NumberTwo;
Write-Host "`nLess Than or Equals";
Test-DotNotation $NumberOne "<=" $NumberTwo;
Test-DotNotation $NumberOne "=<" $NumberTwo;
Test-DotNotation $NumberOne "-le" $NumberTwo;
Write-Host "`nGreater Than or Equals";
Test-DotNotation $NumberOne ">=" $NumberTwo;
Test-DotNotation $NumberOne "=>" $NumberTwo;
Test-DotNotation $NumberOne "-ge" $NumberTwo; Results: Equals
False
False
Less Than
False
False
Greater Than
True
True
Less Than or Equals
False
False
False
Greater Than or Equals
True
True
True
|
|
|
|
dm_4ever
-
Total Posts
:
3673
- Scores: 82
-
Reward points
:
0
- Joined: 6/29/2006
- Location: Orange County, California
-
Status: offline
|
Re:What's the most efficient way to compare two "dotted" numbers?
Tuesday, September 22, 2009 8:32 AM
( permalink)
First...thanks for posting examples of things you use powershell for...I have yet to find the drive to get more involved with it... anyway...one part that you can probably reduce the amount of code might be...
Switch ($Test)
{
"=" {Return $NumberLeft -eq $NumberRight}
"-eq" {Return $NumberLeft -eq $NumberRight}
">" {Return $NumberLeft -gt $NumberRight}
"-gt" {Return $NumberLeft -gt $NumberRight}
"<" {Return $NumberLeft -lt $NumberRight}
"-lt" {Return $NumberLeft -lt $NumberRight}
"<=" {Return $NumberLeft -le $NumberRight}
"=<" {Return $NumberLeft -le $NumberRight}
"-le" {Return $NumberLeft -le $NumberRight}
">=" {Return $NumberLeft -ge $NumberRight}
"=>" {Return $NumberLeft -ge $NumberRight}
"-ge" {Return $NumberLeft -ge $NumberRight}
default { Return -1; }
}
with maybe...
Switch -regex ($Test)
{
"^(=|\-eq)$" {Return $NumberLeft -eq $NumberRight}
"^(\>|\-gt)$" {Return $NumberLeft -gt $NumberRight}
"^(\<|\-lt)$" {Return $NumberLeft -lt $NumberRight}
"^(\<=|=\<|\-le)$" {Return $NumberLeft -le $NumberRight}
"^(\>=|=\>|\-ge)$" {Return $NumberLeft -ge $NumberRight}
default { Return -1; }
}
EDIT://Added more stuff ...so here is a slightly different way of doing the same (very similar to yours...just a bit different)
function Test-DotNotation
{
param ( $strNum1 = "",
$strOp = "",
$strNum2 = "")
if (($strNum1 -eq "") -or ($strOp -eq "") -or `
($strNum2 -eq "")) { return -1; }
switch -regex ($strOp)
{
"^(=|\-eq)$" { if ($strNum1 -eq $strNum2) { return $true } }
}
[regex]$objRegEx = "\d+";
$colMatches1 = $objRegEx.Matches($strNum1);
$colMatches2 = $objRegEx.Matches($strNum2);
if ($colMatches1.Count -gt $colMatches2.Count) { $intMax = $colMatches1.Count; }
else { $intMax = $colMatches2.Count; }
$strNum1 = "";
$strNum2 = "";
for ($intCount = 0; $intCount -lt $intMax; $intCount++)
{
switch ($true)
{
([int]$colMatches1[$intCount].Value.Length -gt [int]$colMatches2[$intCount].Value.Length)
{
$strNum2 += "0" * [math]::abs([int]$colMatches1[$intCount].Value.Length - [int]$colMatches2[$intCount].Value.Length);
}
([int]$colMatches1[$intCount].Value.Length -lt [int]$colMatches2[$intCount].Value.Length)
{
$strNum1 += "0" * [math]::abs([int]$colMatches1[$intCount].Value.Length - [int]$colMatches2[$intCount].Value.Length);
}
}
$strNum1 += $colMatches1[$intCount].Value;
$strNum2 += $colMatches2[$intCount].Value;
}
Switch -regex ($strOp)
{
"^(=|\-eq)$" { Return [int]$strNum1 -eq [int]$strNum2; }
"^(\>|\-gt)$" { Return [int]$strNum1 -gt [int]$strNum2; }
"^(\>=|=\>|\-ge)$" { Return [int]$strNum1 -ge [int]$strNum2; }
"^(\<|\-lt)$" { Return [int]$strNum1 -lt [int]$strNum2; }
"^(\<=|=\<|\-le)$" { Return [int]$strNum1 -le [int]$strNum2; }
default { Return -1; }
}
}
Clear-Host
$strNum1 = "1.1.10.0"
$strNum2 = "0.240.1.3"
Write-Host "Equals";
Test-DotNotation $strNum1 "=" $strNum2;
Test-DotNotation $strNum1 "-eq" $strNum2;
Write-Host "`nLess Than";
Test-DotNotation $strNum1 "<" $strNum2;
Test-DotNotation $strNum1 "-lt" $strNum2;
Write-Host "`nGreater Than";
Test-DotNotation $strNum1 ">" $strNum2;
Test-DotNotation $strNum1 "-gt" $strNum2;
Write-Host "`nLess Than or Equals";
Test-DotNotation $strNum1 "<=" $strNum2;
Test-DotNotation $strNum1 "=<" $strNum2;
Test-DotNotation $strNum1 "-le" $strNum2;
Write-Host "`nGreater Than or Equals";
Test-DotNotation $strNum1 ">=" $strNum2;
Test-DotNotation $strNum1 "=>" $strNum2;
Test-DotNotation $strNum1 "-ge" $strNum2;
<message edited by dm_4ever on Tuesday, September 22, 2009 9:11 AM>
|
|
|
|
turranx
-
Total Posts
:
59
- Scores: 0
-
Reward points
:
0
- Joined: 2/7/2006
- Location: Cincinnati, OH
-
Status: offline
|
Re:What's the most efficient way to compare two "dotted" numbers?
Wednesday, September 23, 2009 2:52 AM
( permalink)
This I like. Very slick. I was hoping there was a way to combine tests. Switch -regex ($Test) { "^(=|\-eq)$" {Return $NumberLeft -eq $NumberRight} "^(\>|\-gt)$" {Return $NumberLeft -gt $NumberRight} "^(\<|\-lt)$" {Return $NumberLeft -lt $NumberRight} "^(\<=|=\<|\-le)$" {Return $NumberLeft -le $NumberRight} "^(\>=|=\>|\-ge)$" {Return $NumberLeft -ge $NumberRight} default { Return -1; } } ...[math]::abs... - You sir, are an overachiever.
|
|
|
|
Online Bookmarks Sharing: