2015-11-10 3 views
14

В моем коде у меня есть два элемента, которые имеют одинаковый возраст "Joe"=>"43" и "Rob"=>"43".Как вернуть элементы массива с наивысшими значениями?

Мой выходной код:

Джо

Я хочу вывести:

Джо и Роб

Потому что имеет наибольшее значение.

Это мой код:

<?php 
    $cur = 1; 

    $age = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43"); 
    $new_array = array(); 
    arsort($age); 
    $new_array = $age; 
    $key = array_search(max($new_array), $new_array); 

    while ($cur > 0) { 
     echo $key; 
     $cur--; 
    } 
?> 
+0

просто для того, чтобы прояснить ситуацию и избежать путаницы. у вас есть многомерный массив ассоциативных массивов. Объект будет чем-то вроде класса. –

+0

Спасибо за tha @ iam-decoder – uno

+0

Вы не должны добавлять значения interget как строку, а как целое: 'array (" Peter "=> 35)'. Целые числа быстрее, чем строки, используйте их там, где вы можете :) – Martijn

ответ

12

Я бы изменить ключи и значения в массиве, а затем сортировать по ключевым и возвращать значения из первый ключ:

$ages = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43"); 
$new = array(); 

foreach ($ages as $name => $age) { 
    $new[$age][] = $name; 
} 

uksort($new, function($ka, $kb) { return $kb - $ka; }); // or just krsort($new); 
$new = array_values($new)[0]; // <- to use this you have to have at least PHP 5.4 

// if you have PHP < 5.4 you can simply do it in two steps: 
// $new = array_values($new); 
// $new = $new[0]; 

See it in action!

EDIT: even simpler!

$ages = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43"); 
$max = max($ages); 
$new = array_keys(array_filter($ages, function ($age) use ($max) { return $age == $max; })); 
+0

лучший, лаконичный, чистый ответ –

+0

ваш ответ в порядке, как есть. единственное, что я могу думать, это то, что они должны будут использовать php 5.4+, чтобы этот скрипт работал с непосредственным доступом к массиву возвращаемого значения на последней строке :) –

+0

@ iam-decoder вы правы, я добавила записку об этом! –

4

Просто проверить его вручную:

$age = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43"); 
$new_array = array(); 
arsort($age); 
$new_array = $age; 
$max = max($new_array); 

$results = array(); 
foreach ($new_array as $key => $val) { 
    if ($val == $max) { 
     $results[] = $key; 
    } 
} 

echo implode(' and ', $results); 
// will output "joe and bob" 
3

Вы можете использовать методы массива next и key.

С следующий() вы переместите указатель массива на одну позицию. С помощью клавиши () вы получите ключ элемента указателя массива. Таким образом, окончательный код будет выглядеть примерно так:

$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43"); 
arsort($age); 
echo key($age); 

next($age); 
echo key($age); 

Check it working here.

+0

Нет, это не самое эффективное решение, так как сортировка имеет сложность 'O (n * log n)': https://en.wikipedia.org/wiki/Sorting_algorithm – svrnm

+0

Вы правы в отношении метода сортировки, спасибо :-) – Miguel

3

Я хотел бы сделать что-то вроде этого

$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43"); 

$max = max($age); //get the highest age 

foreach ($age as $key => $value) { //iterate through $age array 
    if ($value == $max) {   //if the value is equal to max age 
     echo $key."<br />";  // then echo the key 
    } 
} 
9

Использование:

$people = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43"); 
$max = max($people); 
$result = array_filter($people, function($age) use ($max){ return $max == $age; }); 

Результат является:

Array 
(
    [Joe] => 43 
    [Rob] => 43 
) 
+0

Я вижу, мы думаем одинаково :) –

+0

Да, мы сделали это^_^ – evilive

4

Мне нравится ответ @ Маттео-Tassinari и @evilive гораздо больше и хотел сам предложить это.Но так как вопрос о Efficency подошел, вот это решение, используя только одну петлю, и, следовательно, имеет линейную временную сложность:

<?php 
$max = ~PHP_INT_MAX; 
$result = []; 
foreach($age as $key => $value) { 
    if($value > $max) { 
     $result = [ $key => $value ]; 
     $max = $value; 
    } 
    if($value == $max) { 
     $result[$key] = $value; 
    } 
} 
var_dump($result); 

И существует другое решение, которое использует bucket sort:

function bucket($ages) { 
    $buckets = []; 
    foreach($ages as $key => $value) { 
     $buckets[$value][] = $key; 
    } 
    return $buckets[max(array_keys($buckets))]; 
} 

Что касается discusson о Peformance и масштабируемости, я написал небольшой бенчмарк сценария для четырех видов предлагаемых решений (петель, sort, filter, ведра):

<?php 
function loop($ages) { 
    $max = 0; 
    $result = []; 
    foreach($ages as $key => $value) { 
      if($value > $max) { 
        $result = [ $key => $value ]; 
        $max = $value; 
      } 
      if($value == $max) { 
        $result[$key] = $value; 
      } 
    } 
    return array_keys($result); 
} 

function filter($ages) { 
    $max = max($ages); 
    $new = array_filter($ages, function ($age) use ($max) { return $age == $max; }); 
    return array_keys($new); 
} 

function bucket($ages) { 
    $buckets = []; 
    foreach($ages as $key => $value) { 
      $buckets[$value][] = $key; 
    } 
    return $buckets[max(array_keys($buckets))]; 
} 


for($n = 2; $n < 10000000; $n*=2) { 

    $ages = []; 
    for($i = 0; $i < $n; $i++) { 
      $ages['name_'.$i] = rand(0,100); 
    } 

    $start = microtime(true); 
    echo $n.';'; 
    loop($ages); 
    echo (microtime(true) - $start).';'; 
    $start = microtime(true); 
    arsort($ages); 
    echo (microtime(true) - $start).';'; 
    $start = microtime(true); 
    filter($ages); 
    echo (microtime(true) - $start).';'; 
    bucket($ages); 
    echo (microtime(true) - $start).';'; 
    echo PHP_EOL; 
} 

Limited Live Test

Пожалуйста перепроверить, если это право: Использование PHP-5.6.15 в командной строке, мои тайминги выглядеть примерно так:

elements;loop;sort;filter;bucket 
... 
4096;0.001507;0.009868;0.01211;0.01453; 
8192;0.003704;0.002483;0.02488;0.03035; 
16384;0.006660;0.01010;0.05396;0.06723; 
32768;0.01417;0.01271;0.09163;0.1163; 
... 
1048576;0.4227;0.9791;2.983;3.943; 
2097152;0.8572;2.320;6.064;8.020; 
4194304;1.787;4.981;11.90;16.04; 
8388608;3.892;10.84;24.76;33.31; 

Для небольшого числа элементов, разница между методы не очень большие, но, как вы можете видеть, для наибольшего значения метод loop в два раза быстрее, чем sort, в 8 раз быстрее, чем filter и в одиннадцать раз быстрее, чем bucket. Так что если ваш массив огромный, вы должны использовать loop.

+0

Это лучший ответ, по моему мнению, он работает в линейной временной сложности. – Tim

+0

Мое решение с использованием 'max()' и 'array_filter()' должно по-прежнему быть «O (n)», что эквивалентно вычислению эквивалентно этому, не так ли? –

+0

@MatteoTassinari Вычислительная сложность - это не то же самое, что производительность.Если алгоритм работает в O (n^2) для 100 элементов, каждый шаг занимает 1 мс, что составляет 10 секунд. Если он работает в O (n) для 100 предметов, каждый шаг занимает 1 секунду, что составляет 100 секунд. Какой алгоритм лучше? –

Смежные вопросы