在PowerShell数组中找到最接近的数值

4

问:我正在寻找一种更优雅的方法从数组中获取最接近数字的匹配项。
我的处理可能有些复杂。

输入

## A given array A where to search in
$a = (16/10),(16/9),(4/3),(5/4),(21/10),(21/9)  

## A given value B which should be searched for in array A (closest match)
$b = 16/11

期望的输出

"Closest value to 16/11 is 4/3"

我目前用来解决问题的代码

## New array C for the differences of array A - B
$c = $a | %{  [math]::abs($_ - $b) } 

## Measure array C to get lowest value D
$d = $c | measure -Minimum

## Get position E of value D in array C
$e = [array]::IndexOf($c, $d.minimum)

## Position E correlates to array A
echo "Closest value to $b is $($a[$e])

备注

  • 如果哈希表或其他结构更加适合,那么它不一定要是一个数组
  • 我的当前代码输出小数,例如1.33333,而不是分数4/3。最好能够输出分数。
  • 短代码总是更好的。

为了得到期望的输出,最接近的值不应该是4/3而不是16/10吗? - Ryan Bemrose
@RyanBemrose 当然,已经更正了。 - nixda
5个回答

1
$a = (16/10),(16/9),(4/3),(5/4),(21/10),(21/9) 
$b = 16/11
$oldval = $b - $a[0]
$Final = $a[0]
if($oldval -lt 0){$oldval = $oldval * -1}
$a | %{$val = $b - $_
if($val -lt 0 ){$val = $val * -1}
if ($val -lt $oldval){
$oldval = $val
$Final = $_} }
Write-host "$Final is the closest to $b"

这个完美运行了..!! - Chand

0

这是一个使用距离函数进行排序的一行代码:

($a | Sort-Object { [Math]::abs($_ - $b) })[0]

在这种情况下,返回分数是不可能的,因为例如16/10会立即转换为十进制。


0
    ## A given array A where to search in
$a = (16/10),(16/9),(4/3),(5/4),(21/10),(21/9)  

## A given value B which should be searched for in array A (closest match)
$b = 16/11

<#Create a new-Object , we'll use this to store the results in the Foreach Loop#>
$values = [Pscustomobject] @{
                             'result'    = @()
                             'a-values'  = @()
                            }
    
 foreach($aa in $a)
                  {         #round to 2 decimal places and then subtract 
                            #store the result at the 'a-value' used to create that result
                   $values.result += [MATH]::Abs(    [Math]::Round($B,2)`
                                                    -[Math]::Round($aa,2)`
                                                 )                         
                   $values."a-values" += $aa
                  }

# sort ascending and then this gets me the number closest to Zero
$lookFor = $($values.result | Sort-Object )[0]

#the result of the Number closest to $b = 16/11                          
$endresult = $values.'a-values'[  $values.result.indexof($lookfor)  ]

Write-host "the number closest to '$b' is '$endresult'"

Remove-Variable values

请添加更多细节以扩展您的答案,例如工作代码或文档引用。 - Community

0
## A given array A where to search in
$a = '16/10','16/9','4/3','5/4','21/10','21/9'

## A given value B which should be searched for in array A (closest match)
$b = '16/11'

$numericArray = ($a | % { Invoke-Expression $_ })
$test = Invoke-Expression $b
$best = 0
$diff = [double]::MaxValue
for ($i = 1; $i -lt $numericArray.count; $i++) {
    $newdiff = [math]::abs($numericArray[$i] - $test)
    if ($newdiff -lt $diff) {
        $diff = $newdiff
        $best = $i
    }
}

"Closest value to $b is $($a[$best])"

这里的大区别在于输入是字符串而不是数字,因此我们可以保留分数。

安全提示:如果输入来自用户,请勿使用此功能,因为将用户生成的字符串传递给Invoke-Expression显然会引起麻烦。


0
$diff = $b - $a[0]
$min_index = 0
for ($i = 1; $i -lt $a.count; $i++)
{
   $new_diff = $b - $a[$i]
   if ($new_diff -lt $diff)
   {
      $diff = $new_diff
      $min_index = $i
   }
}

Write-Output "Closest value to $b is $($a[$min_index])"

Powershell 不支持分数值...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接