1

I have array with positive int values like [4, 1, 75, 52, 5, 24]. I need to find two values with minimal difference. Also, I need the original keys of those two. So, I sorted the array with asort() to keep the keys. Now when I iterate I have a problem - I can't use $key + 1 to point to next element and using next() and prev() makes it difficult to get the keys (once you use next or prev pointer is moved):

for ($i = 0; $i < count($sorted)-1; $i++) {
  if (current($sorted) - next($sorted) < $min) {
    //echo prev($sorted) - next($sorted) . '<br>'; 
  }
}

What would you do?
(Feel free to alter array in any other form if that makes this easier - asort is not necessary)

If I need to explain one more time: I have a problem with keys. Finding the closest values is not a problem.

GMarco24
  • 410
  • 3
  • 10
  • Possible duplicate of [Find a matching or closest value in an array](https://stackoverflow.com/questions/5464919/find-a-matching-or-closest-value-in-an-array) – Red Bottle Jun 11 '19 at 08:58
  • @here, if my answer doesn't satisfy your expectations, let me know, I will happily remove it :). – Rahul Jun 11 '19 at 10:34

2 Answers2

0

I completely revamped your snippet. You can take whatever you want from below snippet,

$array = [4, 1, 5, 52, 75, 52, 24];
function difference($arr)
{
    $n = count($arr);
// Initialize difference
    // as infinite
    $diff = PHP_INT_MAX;
// Find the min diff by comparing
    // difference of all possible
    // pairs in given array
    $two_values = [];
    for ($i = 0; $i < $n - 1; $i++) {
        for ($j = $i + 1; $j < $n; $j++) {
            if (abs($arr[$i] - $arr[$j]) < $diff) {
                $diff = abs($arr[$i] - $arr[$j]);
                $two_values['values'] = [$arr[$i], $arr[$j]];
                $two_values['keys']   = [$i, $j];
                $two_values['diff']   = $diff;
            }
        }
    }

// Return min diff
    return $two_values;
}
print_r(difference($array));

Demo.

Please let me know if something is not getting.

GMarco24
  • 410
  • 3
  • 10
Rahul
  • 18,271
  • 7
  • 41
  • 60
  • That array_search is not good enough to always target correct key. If you try array like [4,1,5,52,75,52,24] you'll get same key for both 52 values. – GMarco24 Jun 11 '19 at 10:45
  • There is a workaround for it, I updated my answer. Please check now. – Rahul Jun 11 '19 at 10:49
  • You are right! I got your concern, let me rethink on snippet. – Rahul Jun 11 '19 at 10:54
  • But I think you gave me idea. I might create array with original keys and values. That might help. And iterate through [0 => ['original_key' => 1, 'value' => 1], 1 => ['original_key' => 0, 'value' => 4]...]. That way I can use $array[$key+1]['value'] to get next value and $array[$key+1]['original_key'] will return initial key value – GMarco24 Jun 11 '19 at 10:54
  • I am checking again, give me sometime. – Rahul Jun 11 '19 at 10:55
  • Now Check I completely changed the snippet. – Rahul Jun 11 '19 at 11:21
0

I found my own way to do this using additional array with keys and array_multisort()

$numbers = [4, 1, 75, 1, 52, 5, 52, 24, 52];
$ar = [];
$mins = [];
$min = PHP_INT_MAX;
foreach ($numbers as $key => $number) {
    $ar[] = ['key' => $key, 'number' => $number];
}

array_multisort(array_column($ar, 'number'), SORT_DESC, array_column($ar, 'key'), SORT_DESC, $ar );

foreach ($ar as $key => $value) {
    if (!isset($ar[$key + 1])) break;
    if ($value['number'] - $ar[$key + 1]['number'] <= $min) {
        $min = $value['number'] - $ar[$key + 1]['number'];
        $mins = [$ar[$key + 1], $ar[$key]];
    }
}
GMarco24
  • 410
  • 3
  • 10