E
E
ekaramazov2018-02-12 16:50:59
PHP
ekaramazov, 2018-02-12 16:50:59

How to sort an array by nearest number?

There is an array

$arr = array(
    array('id'=>1,'value'=>4),
    array('id'=>2,'value'=>6),
    array('id'=>3,'value'=>2.5),
    array('id'=>4,'value'=>-2),
    array('id'=>5,'value'=>3),
    array('id'=>6,'value'=>2.6),
    array('id'=>7,'value'=>3),
    array('id'=>8,'value'=>3),		
    array('id'=>9,'value'=>-3),		
  );

and a number, for example, 2.6, and you need to sort the array so that the closest to it are the first
usort($arr, function($a, $b){
            $c_v = 2.6;     
            return abs(($a['value'] - $c_v) - ($b['value'] - $c_v)); // тут возможно бред - уже изменял 100000 раз и запутался
        });

it is not possible to sort by the nearest ones in the array, including negative numbers and float
should turn out:
array('id'=>6,'value'=>2.6),
array('id'=>3,'value'=>2.5),
array('id'=>6,'value'=>4),
array('id'=>5,'value'=>3),
array('id'=>7,'value'=>3),
array('id'=>8,'value'=>3),
.........

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2018-02-12
@ekaramazov

return abs(($a['value'] - $c_v) - ($b['value'] - $c_v)); // тут возможно бред - уже изменял 100000 раз и запутался

Yes, of course it's bullshit.
First, it is necessary to calculate not the absolute value of the difference of the differences, but the difference of the absolute values ​​of the differences.
Secondly, if the comparison function returns a non-integer result, it will be cast to an integer, which - surprise, surprise - may turn out to be zero, in which case the compared values ​​will be considered equal, although this may not be the case. That is, it is necessary to guarantee the return of a result that is irreducible to zero (unless, of course, it is initially not zero).
In general, your sorting could look something like this:
usort($arr, function($a, $b){
  $c_v = 2.6;
  return ceil(abs($a['value'] - $c_v) - abs($b['value'] - $c_v));
});

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question