Powershell比较数组元素

时间:2018-06-17 19:53:04

标签: arrays powershell

我可能在这里遗漏了一些简单的事情,所以我提前道歉。我也知道可能有更好的方法,所以我也可以这样做。

我试图运行一个PowerShell脚本来查看一个值数组,比较它们以查看数组中两个元素之间差异的值。

以下是我用来测试的示例数据集,该数据集从CSV导入PowerShell:

1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.7, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.7, 2.9, 3.0

我想要完成的是运行此列表并将第二个条目与第一个条目进行比较,第三个条目与第二个条目进行比较,第四个条目与第三个条目进行比较,等等,仅将元素添加到$export它的值比前一个元素至少大0.2。

以下是我尝试的内容:

$import = get-content C:/pathtoCSVfile
$count = $import.Length-1;
$current=0;

Do 
{    
    $current=$current+1;
    $previous=$current-1

    if (($import[$current]-$import[$previous]) -ge 0.2)
    {
        $export=$export+$import[$current]+"`r`n";
    }
} 
until ($current -eq $count)

现在我通过Trace on运行它,它将值分配给$current$previous并按照每个循环上if条件中的描述运行两者的减法通过,但只有2.7($import[14]-$import[13])的值是注册if条件已经满足,因此在$export中只留下2.7的单个值。我预计其他值(1.7,1.9和2.9)也会添加到$export变量中。

同样,这可能是我忽视的愚蠢/明显的东西,但我似乎无法弄明白。提前感谢您提供的任何见解。

1 个答案:

答案 0 :(得分:5)

问题是小数部分在隐式使用的[double] data type中没有完全表示,导致舍入错误导致您的{{1比较产生意外结果

一个带有-ge 0.2值的简单示例,这是PowerShell隐式使用的带有小数点的数字文字的内容:

[double]

如果您强制计算使用[decimal] type而不是,则问题就会消失。

应用于上面的示例(将PS> 2.7 - 2.5 -ge 0.2 True # OK, but only accidentally so, due to the specific input numbers. PS> 1.7 - 1.5 -ge 0.2 False # !! Due to the inexact internally binary [double] representation. 附加到PowerShell中的数字文字,使其成为d):

[decimal]

应用于更加PowerShell惯用的代码重构:

PS> 1.7d - 1.5d -ge 0.2d
True # OK - Comparison is now exact, due to [decimal] values.

以上产量:

# Sample input; note that floating-point number literals such as 1.0 default to [double]
# Similarly, performing arithmetic on *strings* that look like floating-point numbers
# defaults to [double], and Import-Csv always creates string properties.
$numbers = 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.7, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.7, 2.9, 3.0

# Collect those array elements that are >= 0.2 than their preceding element
# in output *array* $exports.
$exports = foreach ($ndx in 1..($numbers.Count - 1)) {
  if ([decimal] $numbers[$ndx] - [decimal] $numbers[$ndx-1] -ge 0.2d) {
    $numbers[$ndx] 
  }
}

# Output the result array.
# To create a multi-line string representation, use $exports -join "`r`n"
$exports