2012-04-25 3 views
0

Вот два массива, которые нужно сравнить.эффективный способ сравнения php-массива

array_a(
[0] => array('userid' => aaa, 'created_time' => XXXX,), 
[1] => array('userid' => bbb, 'created_time' => XXXX,), 
[2] => array('userid' => ccc, 'created_time' => XXXX,) 
) 


array_b(
[0] => array('userid' => aaa, 'created_time' => XXXX,), 
[1] => array('userid' => ccc, 'created_time' => XXXX,), 
[2] => array('userid' => ddd, 'created_time' => XXXX,) 
) 

Я хочу получить все элементы, которые соответствуют следующим условиям: Идентификатор_пользователь array_a находится в array_b и created_time array_a является более новым, чем array_b-х

Я использую следующий код, чтобы сделать это, но это займет если массив массивный.

for array_a{ 
    for array_b{ 
    if (a[user_id] = b[user_id] && a[created_time] > b[created_time]) { 
     //target got 
    } 
    } 
} 

Есть ли способ эффективно выполнять эту логику?

Спасибо за ответ. Идентификаторы уникальны. Как преобразовать array_a ( [0] => массив ('userid' => aaa, 'created_time' => XXXX,), [1] => array ('userid' => bbb, 'created_time' => ХХХХ,), )

в массив формы (ааа => ХХХХ, БББ => XXXX) ?

+1

Единственное, что вы можете здесь сделать, это изменить свои массивы, чтобы они выглядели как 'array ('aaa' => XXXX, 'bbb' => XXXX)'. Особенно, если вы можете сделать это до того, как данные попадут в этот формат (что крайне непригодно для работы). – Jon

+3

Если все идентификаторы пользователей уникальны, вы можете сначала сопоставить массив B с 'arrayB [user_id] => created_time'. Затем вы можете перебирать массив A и просто искать идентификатор пользователя в массиве B ('O (1)'). Это около 'O (2n)' вместо 'O (n^2)'. –

+0

Являются ли пользователь в отсортированном порядке? – Jack

ответ

1
foreach($array_a as $arr) 
    $tmp[$arr['userid']] = $arr['created_time']; //rebulding first array 

foreach($array_b as $arr) 
    if(isset($tmp[$arr['userid']]) && $arr['created_time'] < $tmp[$arr['userid']]){ 
    //target 
    } 

, как сначала вы должны восстановить один из вашего массива структурировать подходит для следующего шага, где вы ищете для элементов, удовлетворяющих ваше состояние. Это решение должно быть лучше, чем ваше, потому что оно имеет гораздо меньшее количество циклов (2 * n вместо n^2)

+4

Ну, а как насчет этого? Вы задаете себе вопрос? – Jon

+0

ОК, я обновил свой код для тех ленивых b ******, которые хотят, чтобы все было подано на серебряной тарелке (извините за мой английский, надеюсь, вы поймете меня;) – miro

+0

Прошу прощения, но ваш код будет расточать много памяти, чтобы сделать общее количество ничего полезного. Вы пропустили часть, в которой роль 'created_time' играет роль? – Jon

0

Вы можете рассмотреть использование идентификатора пользователя каждого элемента в качестве ключа массива. Это позволяет вам искать правильный элемент в B в O (1) раз.

0

Сортируйте оба массива по идентификатору пользователя, а затем создайте время. Порядок все еще O (N^2), но число сравнений значительно уменьшается. Однако, поскольку вы ищете явное совпадение с идентификатором пользователя, то преобразование массивов в массив ('aaa' => array (0 => 'created_time', 1 => 'created_time' ...) ...), затем получение значение array_intersect (array_a, array_b) даст вам все обычные идентификаторы пользователей.

0
$b_index = 0; 
for ($a_index = 0; $a_index < count($a); $a_index++) 
{ 
    if ($a[$a_index]['userid'] == $b[$b_index]['userid']) 
    { 
     if ($a[$a_index]['created_time'] >= $b[$b_index]['created_time']) 
      $array[] = $a[$a_index]; 
     $b_index++; 
    } 
} 

Если иденты оба сортируется в том же порядке, что вам не нужно, чтобы по сравнению каждый идентификатор пользователя в каждом идентификаторе пользователя в б посмотреть на матч. По крайней мере, это должно быть меньше сравнений.

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