My user defined comparison compare function is defined with an array:
$boardkey_to_values=Array(19=>2601248,23=>2601248,39=>2603445,
43=>2256319,47=>2632006,59=>2603445,63=>2232152,67=>2260713,71=>2632006,...)
so 23>19
EDIT:23=19
, 39>19
, 39<23
,...
I have an array of values $board_id
, and I want to get the array of all the keys for the minimum values.
Here's my solution, but I don't think it is really intuitive.
$min_key=Array(0);
foreach ($board_id as $key => $value) {
if ($boardkey_to_values[$board_id[$min_key[0]]]>$boardkey_to_values[$value])
$min_key=Array($key);
if ($boardkey_to_values[$board_id[$min_key[0]]]==$boardkey_to_values[$value] && $min_key[0]!=$key)
$min_key[]=$key;
}
Here is an example to show how this should behave:
say $board_id = [19,23,39,47,71]
it will look at the values corresponding to this numbers [2601248,2601248,2603445,2632006,2632006]
it looks for the smallest value: 2601248
so the result ($min_key
should be [19,23]
)
-
\$\begingroup\$ Why is 23 > 19 when they both map to the same value? Shouldn't they be equal? \$\endgroup\$David Harkness– David Harkness2013年03月26日 22:00:49 +00:00Commented Mar 26, 2013 at 22:00
-
\$\begingroup\$ Yes you're right 23=19, I have edited my question \$\endgroup\$edi9999– edi99992013年03月27日 07:16:26 +00:00Commented Mar 27, 2013 at 7:16
2 Answers 2
This should be O(n)* where n is count($board_id)
.
$mapped = array_map(function ($id) use ($boardkey_to_values) {
return array($boardkey_to_values[$id], $id);
}, $board_id);
asort($mapped);
list($min_value, $id) = reset($mapped);
$min_ids = array($id);
while (list($value, $id) = next($mapped)) {
if ($value == $min_value) {
$min_ids[] = $id;
}
else {
break;
}
}
* ignoring the call to asort
which is probably O(n log n).
-
\$\begingroup\$ What exactly does the
use
keyword do after the parameters of an anonymous function ? \$\endgroup\$edi9999– edi99992013年03月27日 07:27:06 +00:00Commented Mar 27, 2013 at 7:27 -
1\$\begingroup\$ It allows the anonymous function to access the named variable. Without it the function can only access the local variables and arguments it declares. \$\endgroup\$David Harkness– David Harkness2013年03月27日 07:55:10 +00:00Commented Mar 27, 2013 at 7:55
You could try doing it this way:
$min_key = null;
asort($boardkey_to_values);
foreach(array_count_values($boardkey_to_values) as $val) {
$min_key = array_slice( array_keys($boardkey_to_values), $val );
break;
}
I believe that would accomplish what you're trying to do.
-
\$\begingroup\$ Your function is very slow compared to mine, because array_slice is slow given the size of the
$boardkey_to_values
(more than 40 000 entries). And it isn't exactly what I meant (cf edit for the example) \$\endgroup\$edi9999– edi99992013年02月24日 21:29:07 +00:00Commented Feb 24, 2013 at 21:29