2012-03-05 2 views
1

У меня есть два массива, мне нужно сравнить ....Сравнение двух массивов сохранить данные спичек

$ Пейте составлять список присяжных заседателей

(
[0] => Drink Object 
    (
     [top_id] => 40C6-88 
     [name] => Pepsi 
     [drink_id] => E936 
    ) 

[1] => Drink Object 
    (
     [top_id] => 46DB-9E 
     [name] => Orange Juice 
     [drink_id] => E936 
    ) 
) 

[2] => Drink Object 
    (
     [top_id] => 5J71-4F79 
     [name] => Dr Pepper  
     [drink_id] => E936 
    ) 

$ DrinkItem массив

(
[0] => DrinkItem Object 
    (
     [bottom_id] => 45BD-92DD 
     [name] => Diet Coke  
     [drink_template_id] => 3B2A-4D82 
    ) 

[1] => DrinkItem Object 
    (
     [bottom_id] => 4A71-8F79 
     [name] => Orange Juice  
     [drink_template_id] => 3B2A-4D82 
    ) 


) 

.. Если name соответствует одному из имен в массиве DrinkItem Мне нужно сохранить top_id этого элемента.

Я пытался сделать что-то вроде:

foreach ($Drink as $d) { 
    foreach ($DrinkItem as $item){ 
     if ($d->name == $item->name){ 
      $match = $d->top_id; 
     } 
    } 
} 

Но я мог бы быть способ покинуть базу здесь. Если есть лучший подход для хранения идентификатора совпадений или если я на правильном пути, любая помощь очень ценится!

+0

Поскольку в массиве есть объекты, петли - единственное решение, которое приходит мне на ум. Вы можете удалить совпадения из массивов, чтобы сократить циклы. – Corubba

+0

Вам нужно найти все 'top_id', которые соответствуют критерию? – Irfy

+1

Вы на правильном пути, но это не самое * эффективное * решение. Он будет выполняться в [O (n^2) раз] (http://en.wikipedia.org/wiki/Big_O_notation). Если эффективность важна, дайте мне знать, и я смогу дать вам лучшее решение.В противном случае есть что сказать, чтобы это было легко понять. Примечание. Мои альтернативные решения, вероятно, будут иметь дело с хешированием. Перетаскивание эффективности памяти в пользу эффективности времени. – ShaneC

ответ

2

Вы могли бы быть лучше создать индекс первого:

$drinkindex = array(); 

// Note that names need to be unique. 
foreach ($Drink as $d) { 
    $drinkindex[$d->name] = $d->top_id; 
} 

$matches = array(); 
foreach ($DrinkItem as $di) { 
    $match = $drinkindex[$di->name]; 
    if ($match!==NULL) { 
     $matches[$match] = True; 
    } 
} 

// $matches is a set of top_id. 
// If you may have duplicates and you want those represented, use a list instead. 

Если вам нужен весь Drink объект, а не только top_id, рассмотреть возможность использования массива пересечения, например, так:

function namecompare($a, $b) { 
    if ($a->name === $b->name) { 
     return 0; 
    } else { 
     return ($a->name < $b->name) ? -1: 1; 
    } 
} 

$intersection = array_uintersect($Drink, $Drinkitem, 'namecompare'); 

var_dump($intersection); // contains $Drink[1]; 
+0

Френсис Авила = мой герой. Спасибо, человек тон, выше и выше. Очень полезно! – mstef

1

Ваш подход, очевидно, O(n*m).

n и m обозначают длины массивов $Drink и $DrinkItem.

Вы можете решить эту проблему в O (n + m) раз, при условии, что у вас есть доступ к карте с хэш-функцией с амортизированной производительностью вставки/выборки O(1).

  1. Инициализировать пустую карту и пустой список.
  2. Истерируйте через $Drink массив и сохраните каждый объект на карте, используя его name в качестве ключа.
  3. Итерации через $DrinkItem и для каждого $drink_item, проверьте, соответствует ли $drink_item->name объект Drink на карте.
    • Если это так, добавьте отображаемый Drink объект в список top_id.

Список содержит top_id с, и вы получите их в O(n+m) время.

Редактировать: сообщение Франциска Авила содержит фактический код PHP, который делает именно это.

+0

спасибо Ирфи! (на самом деле очень полезно видеть, как это свернулось, а затем увидеть его в действии) – mstef

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