Find nearest numerical value in Powershell arrays

Q: I'm looking for a more elegant way to get the closest match of a number from an array. I can have difficult things.

Input

## 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

      

Desired output

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

      

My current code for solving the problem

## 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])

      

Notes

  • It doesn't have to be an array if a hash table or something else is better suited
  • My current code outputs decimal numbers like 1.33333

    , instead of fractions 4/3

    . It would be nice to withdraw the faction
  • Shortcode is always better
+3


source to share


3 answers


$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"

      



+1


source


## 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])"

      

The big difference here is that the inputs are strings, not numbers, so we can keep fractions.



Safety note . Don't use this if the input is owned by the user, as passing user generated strings to Invoke-Expression is obviously a recipe for the problem.

0


source


$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 dose does not support fraction values ​​...

0


source







All Articles