2016-12-02 5 views
3

У меня есть 2 массива данных из разных источников данных в разных форматах, но они представляют одни и те же ресурсы. Таким образом, id в одном - это то же, что и guid.PHP-массив различных типов

В настоящее время я конвертирую один из массивов в соответствие друг с другом, а затем запускаю их через array_udiff, чтобы получить разницу.

Однако мне нужно сравнить 3 свойства, чтобы проверить, соответствуют ли они, поэтому я не могу вернуть -1,0,1, поскольку 3 поля либо совпадают, либо не совпадают.

Если я просто возвращают -1 или 0, он работает по сравнению с $a$b, но терпит неудачу по сравнению с $b$a

$arr_a = [['id'=>1, 'a'=>1, 'b'=>0],['id'=>2, 'a'=>2, 'b'=>3],['id'=>3, 'a'=>1, 'b'=>0]]; 
$arr_b = [['id'=>3, 'a'=>1, 'b'=>0],['id'=>4, 'a'=>2, 'b'=>3],['id'=>5, 'a'=>1, 'b'=>0]]; 

function diff($a, $b) { 
    if(($a['id'] == $b['id']) 
     && ($a['a'] == $b['a']) 
     && ($a['b'] == $b['b']) 
    ) { 
    return 0; 
    } else { 
    return -1; 
    } 

$not_in_b = array_udiff($arr_a, $arr_b,'diff'); 
$not_in_a = array_udiff($arr_b, $arr_a,'diff'); 

print_r($not_in_b); 
print_r($not_in_a); 

Вышеприведенные возвращается ...

Array 
(
    [0] => Array 
     (
      [id] => 1 
      [a] => 1 
      [b] => 0 
     ) 

    [1] => Array 
     (
      [id] => 2 
      [a] => 2 
      [b] => 3 
     ) 

) 
Array 
(
    [0] => Array 
     (
      [id] => 3 
      [a] => 1 
      [b] => 0 
     ) 

    [1] => Array 
     (
      [id] => 4 
      [a] => 2 
      [b] => 3 
     ) 

    [2] => Array 
     (
      [id] => 5 
      [a] => 1 
      [b] => 0 
     ) 

) 

Как вы можете видеть разность $a до $b работ, но $b до $a не ...

Как я могу сравнить несколько Воулс, как это равенство ...

UPDATE

Это работает, но делает два массива с тремя идентифицирующих значениями свойств в качестве ключей ...

$arr_a = [['id'=>1, 'a'=>1, 'b'=>0],['id'=>2, 'a'=>2, 'b'=>3],['id'=>3, 'a'=>1, 'b'=>0]]; 
$arr_b = [['id'=>3, 'a'=>1, 'b'=>0],['id'=>4, 'a'=>2, 'b'=>3],['id'=>5, 'a'=>1, 'b'=>0]]; 

$arra_a_keys=[]; 
foreach($arr_a as $item) { 
    $arra_a_keys[$item['id'].'_'.$item['a'].'_'.$item['b']] = $item; 
} 

$arra_b_keys=[]; 
foreach($arr_b as $item) { 
    $arra_b_keys[$item['id'].'_'.$item['a'].'_'.$item['b']] = $item; 
} 

$not_in_b = array_diff_key($arra_a_keys, $arra_b_keys); 
$not_in_a = array_diff_key($arra_b_keys, $arra_a_keys); 

print_r($not_in_b); 
print_r($not_in_a); 
+2

«не работают». Покажите код, который вы пробовали, и укажите, в каком направлении он не работает. –

+0

Какие элементы сравнивают критерии? только 'id' и' guid' должны совпадать? – sevavietl

+0

@PatrickQ Я добавил пример с некоторыми подробностями ... –

ответ

0

Вы можете использовать Еогеасп для макияжа массива сравнимой

$ids1 = []; 
    foreach($a as $v1){ 
     $i1[] = $v1['id']; 
    } 
    $ids2 = []; 

    foreach($b as $v2){ 
     $i2[] = $v2['guid']; 
    } 
    $one_notin_two = array_diff($i1,$i2); 
    $two_notin_one = array_diff($i2,$i1); 
1

для сравнения по идентификатору ы только вы можете сделать следующее:

$ids = array_column($a, 'id'); 
$guids = array_column($b, 'guid'); 

$not_in_b = array_filter($a, function ($item) use ($guids) { 
    return !in_array($item['id'], $guids); 
}); 
$not_in_a = array_filter($b, function ($item) use ($ids) { 
    return !in_array($item['guid'], $ids); 
}); 

Вот working demo.

Дополнение

Кроме того, вы можете сделать это с array_udiff:

$compareFunction = function ($a, $b) { 
    $id1 = isset($a['id']) ? $a['id'] : $a['guid']; 
    $id2 = isset($b['id']) ? $b['id'] : $b['guid']; 

    return strcmp($id1, $id2); 
}; 

$not_in_b = array_udiff($a, $b, $compareFunction); 
$not_in_a = array_udiff($b, $a, $compareFunction); 

Вот working demo.

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

Функция сравнения должна возвращать целое число меньше, равно или больше нуля, если первый аргумент считается соответственно, меньше, равна или больше, чем второй.

Но это также сортировочные трюки программист, потому что он ожидал, что в функции int callback (mixed $a, mixed $b)$a происходит от $array1 и $b происходит от $array2. Это не относится к делу. Вы можете прочитать this article, чтобы узнать больше. Поэтому я считаю, что решение array_filter более понятно

0

Вы можете решить это, используя array_column() и array_diff().

Вот пример код: See Live Demo

$a = [['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4]]; 
$b = [['guid' => 3], ['guid' => 4], ['guid' => 6], ['guid' => 7]]; 

$a = array_column($a, 'id'); 
$b = array_column($b, 'guid'); 

$not_in_b = array_diff($a, $b); 
$not_in_a = array_diff($b, $a); 

Надеется, что она должна быть решена вашей проблема. Спасибо.

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