Удаление дубликатов в массиве через рекурсию в PHP

столкнулся с интересной ситуацией:

  • есть некий массив $arr= ['зеленый','коричневый','синий','коричневый','красный','синий','черный','фиолетовый','коричневый','синий'], в котором необходимо удалить некий элементы и его возможные дубликаты по значению, к примеру 'синий'.
  • есть функция:
function del_by_value($arr, $del_value){   
    
    if (($key = array_search($del_value, $arr)) !== FALSE) { //единично находим интересующий элемент возвращает его в переменную.
        
        unset($arr[$key]);// удаляем его

        del_by_value($arr, $del_value); // рекурсивно вызываем функцию для проверки массива, и возможного удаления дубликатов 
           
        }
     return $arr;// если элемент (значение) не найден, то возвращаем массив.
   
}

$arr = del_by_value($arr, 'синий');

По логике, функция должна пройти по всем элементам и вернуть массив без дубликатов, на практике возвращается:

array(9) {
  [0] =>
  string(14) "зеленый"
  [1] =>
  string(20) "коричневый"
  [3] =>
  string(20) "коричневый"
  [4] =>
  string(14) "красный"
  [5] =>
  string(10) "синий"
  [6] =>
  string(12) "черный"
  [7] =>
  string(20) "фиолетовый"
  [8] =>
  string(20) "коричневый"
  [9] =>
  string(10) "синий"
}

T.e. удален только первый элемент. Рекурсия работает и, если проверять на разных участках кода, то массив с удаленным элементами появляется на 3-ей итерации:

unset($arr[$key]);// удаляем его
 var_dump($arr);

array(7) {
  [0] =>
  string(14) "зеленый"
  [1] =>
  string(20) "коричневый"
  [3] =>
  string(20) "коричневый"
  [4] =>
  string(14) "красный"
  [6] =>
  string(12) "черный"
  [7] =>
  string(20) "фиолетовый"
  [8] =>
  string(20) "коричневый"
}

Однако функция возвращает не этот результат. Предполагаю, что нужно копать в вопрос с памятью php, он как-то логично для себя заносит результаты работы с $arr в другой последовательности и возвращает только первую итерацию?


Ответы (2 шт):

Автор решения: Виктор

Исправил на полную прогу

$arr = ['зеленый','коричневый','синий','коричневый','красный','синий','черный','фиолетовый','коричневый','синий'];

function del_by_value($arr, $del_value){   
    
    if (($key = array_search($del_value, $arr)) !== FALSE) { //единично находим интересующий элемент возвращает его в переменную.
        
        unset($arr[$key]);// удаляем его

        $arr = del_by_value($arr, $del_value); // рекурсивно вызываем функцию для проверки массива, и возможного удаления дубликатов 
           
        }
     return $arr;// если элемент (значение) не найден, то возвращаем массив.
   
}

$n = del_by_value($arr, 'синий');

var_dump($n);

Вывод на экран:

array(7) {
[0] =>
string(14) "зеленый"
[1] =>
string(20) "коричневый"
[3] =>
string(20) "коричневый"
[4] =>
string(14) "красный"
[6] =>
string(12) "черный"
[7] =>
string(20) "фиолетовый"
[8] =>
string(20) "коричневый"
}
→ Ссылка
Автор решения: Денис

@Виктор и @teran помогли мне разобраться в моем вопросе, я забыл перезаписать переменную $arr на втором вызове функции, но если вдруг кому - то в качествен изучения рекурсии и практики будет интересно, то думаю стоит оставить данную реализацию поиска для изучения.

Рабочая реализация алгоритма приведена @Виктор выше.

→ Ссылка