2012-01-01 6 views
11

Так что это то, что меня беспокоит.PHP - Как сравнить два массива и удалить повторяющиеся значения

У меня есть два массива:

$array1 = array('[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]'); 
$array2 = array('value1' ,'demo' ,'value2' ,'some' ,'value3'); 

Теперь я хочу, чтобы сравнить эти два массива, и удалить все повторяющиеся значения.
В конце я хочу, чтобы эти два массива, но без «демо» и «некоторые» значения в них.
Я хочу удалить все значения из массива, имеющие один и тот же индексный ключ и значение.
У Array всегда будет одинаковое количество значений и индексов, я хочу сравнить их и удалить записи, имеющие одинаковый индексный ключ и значение, из обоих.

Я сейчас делаю что-то вроде этого:

$clean1 = array(); 
$clean2 = array();  

foreach($array1 as $key => $value) 
{ 
    if($value !== $array2[$key]) 
    { 
     $clean1[$key] = $value; 
     $clean2[$key] = $array2[$key]; 
    } 
} 

var_export($clean1); 
echo "<br />"; 
var_export($clean2); 

И это работает! Но им интересно, есть ли другой способ сделать это? Может быть, без использования цикла foreach? Есть ли более элегантный способ сделать это?

+3

Можете ли вы определить, что «элегантно» для вас? Я не вижу здесь проблем ... – nmagerko

+3

Это всегда будет требовать линейного поиска. В этом отношении ваше решение является наиболее эффективным. – You

ответ

21
array_unique(array_merge($arr_1, $arr_2)); 

или вы можете сделать:

$arr_1 = array_diff($arr_1, $arr_2); 
$arr_2 = array_diff($arr_2, $arr_1); 

я думаю ...

+0

Спасибо! Второй - «элегантный»! Но array_diff отключает ключи от arr_1, которые не присутствуют в $ arr_2, и возвращает этот массив с ключами, которые не в порядке.И это может быть проблемой для меня :(Мне нужен новый массив, который начинается с 0: S. Есть ли способ сбросить ключи массива, если у меня есть такие ключи, как 0, 3, 7, я могу сбросить их на 1,2, 3? Если нет, то Il looust придерживается первого цикла foreach. – Limeni

+4

$ arr_1 = array_values ​​($ arr_1); должно работать –

+0

yup довольно хорошо, чтобы не перебирать глупые петли PHP xD –

4

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

$clean1 = array_diff($array1, $array2); 

http://php.net/manual/en/function.array-diff.php

+0

Спасибо, второй - «элегантный»! , он array_diff отключает ключи от arr_1, которые не присутствуют в $ arr_2. И это может быть проблемой для меня :(Мне нужен новый массив, который начинается с 0: S Есть ли способ сбросить ключи массива, если у меня есть ключи вроде 0 , 3, 7, могу ли я их сбросить до 1,2,3? – Limeni

0

С $array1 и $array2 всегда такой же длины, вы могли бы сделать что-то вроде этого:

<?php 

    $array1 = array('[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]'); 
    $array2 = array('value1' ,'demo' ,'value2' ,'some' ,'value3'); 

    $map = array_combine($array1,$array2); 
    $map = array_filter($map ,function ($item) use (&$map) { 
     $keep_data = ($item != key($map)); 
     next($map); 
     return $keep_data; 
    }); 

    $clean1 = array_keys($map); 
    $clean2 = array_values($map); 

    var_export($clean1); 
    echo "<br />"; 
    var_export($clean2); 

?> 

это лучше? Вы решаете

+0

Кого, для меня это сложнее. Я старался переборщить с петлей foreach, но похоже, что это лучший способ сделать это. по крайней мере для меня, для вас это может быть более ясным. Спасибо за комментарий! – Limeni

+1

Yup ... согласился ... и это в 3 раза медленнее :) – Dancrumb

0

что?

$res = array_diff($array1, $array_intersect($array1, $array2)); 
$reindexed = array_combine(array_keys($res), array_values($res)); 

или просто способ, если ключи не нужны

array_values(array_diff($array1, $array_intersect($array1, $array2))); 
1
$clean1 = array_diff($array1, $array2); 
$clean2 = array_diff($array2, $array1); 
$final_output = array_merge($clean1, $clean2); 
+1

Пожалуйста, добавьте некоторое объяснение, чтобы люди могли узнать, почему это работает – jou

0

Ваше решение, безусловно, самый «элегантный» (то есть самый простой для чтения, и наименьшее количество кода), но здесь это другое решение, которое использует array_diff_ukey(). Он сохраняет ключи и ставит их в порядке возрастания, как вы просили.

$array1 = ['[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]']; 
$array2 = ['value1' ,'demo' ,'value2' ,'some' ,'value3']; 

$clean1 = $array1; 

$clean2 = array_diff_ukey(
    $array2, 
    $array1, 
    // Need to have "&" so the values get set. 
    function($a, $b) use (&$clean1, $array1, $array2) { 

     // Use isset() just in case keys are not identical 
     // or arrays are not the same length. 
     if (isset($array2[$b]) && $array2[$b] === $array1[$b]) { 
      unset($clean1[$b]); 
     } 

     return strcmp($array2[$a], $array1[$b]); 

}); 

print_r($clean1); 
print_r($clean2); 

Вернется это:

Array 
(
    [0] => [param1] 
    [2] => [param2] 
    [4] => [param3] 
) 
Array 
(
    [0] => value1 
    [2] => value2 
    [4] => value3 
) 

Работа пример here.

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