array_unique

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

array_uniqueУдаляет повторяющиеся значения из массива

Описание

function array_unique(array $array, int $flags = SORT_STRING): array

Функция принимает входной массив array и возвращает новый массив без повторных значений.

Обратите внимание, функция сохранит ключи исходного массива. Функция сохранит ключ и значение первого одинакового элемента, если при заданных флагах flags окажутся равными несколько элементов.

Замечание:

Функция сохраняет первый элемент и считает два элемента равными, только если верно выражение (string) $elem1 === (string) $elem2, — когда строковое представление элементов тождественно.

Список параметров

array

Входной массив.

flags

Следующие значения необязательного второго параметра flags изменяют поведение сравнения:

Флаги типов сравнения:

  • SORT_REGULAR — нормальное сравнение элементов, без изменения типов

  • SORT_NUMERIC — элементы сравниваются как числа

  • SORT_STRING — элементы сравниваются как строки

  • SORT_LOCALE_STRING — элементы сравниваются как строки на основе текущих языковых настроек

Возвращаемые значения

Функция возвращает отфильтрованный массив.

Список изменений

Версия Описание
7.2.0 Раньше со значением SORT_STRING для параметра flags функция копировала массив array, удаляла из копии неуникальные элементы и после этого внутренне не упаковывала массив. Теперь функция создаёт новый массив и добавляет в него уникальные элементы. Это иногда приводит к разным числовым индексам.

Примеры

Пример #1 Пример получения уникальных значений массива функцией array_unique()

<?php

$input = ["a" => "green", "red", "b" => "green", "blue", "red"];
$result = array_unique($input);
print_r($result);

?>

Результат выполнения приведённого примера:

Array
(
    [a] => green
    [0] => red
    [1] => blue
)

Пример #2 Пример поведения функции array_unique() со значениями разных типов

<?php

$input = [4, "4", "3", 4, 3, "3"];
$result = array_unique($input);
var_dump($result);

?>

Результат выполнения приведённого примера:

array(2) {
  [0] => int(4)
  [2] => string(1) "3"
}

Примечания

Замечание:

Обратите внимание, функция array_unique() не рассчитана на работу с многомерными массивами.

Смотрите также

  • array_count_values() - Подсчитывает количество вхождений каждого отдельного значения в массиве

Добавить

Примечания пользователей 35 notes

up
324
Ghanshyam Katriya(anshkatriya at gmail)
11 years ago
Create multidimensional array unique for any single key index.
e.g I want to create multi dimentional unique array for specific code

Code : 
My array is like this,

<?php
$details = array(
    0 => array("id"=>"1", "name"=>"Mike",    "num"=>"9876543210"),
    1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
    2 => array("id"=>"1", "name"=>"Mathew",  "num"=>"784581254"),
);
?>

You can make it unique for any field like id, name or num.

I have develop this function for same : 
<?php
function unique_multidim_array($array, $key) {
    $temp_array = array();
    $i = 0;
    $key_array = array();
    
    foreach($array as $val) {
        if (!in_array($val[$key], $key_array)) {
            $key_array[$i] = $val[$key];
            $temp_array[$i] = $val;
        }
        $i++;
    }
    return $temp_array;
}
?>

Now, call this function anywhere from your code,

something like this,
<?php
$details = unique_multidim_array($details,'id');
?>

Output will be like this :
<?php
$details = array(
    0 => array("id"=>"1","name"=>"Mike","num"=>"9876543210"),
    1 => array("id"=>"2","name"=>"Carissa","num"=>"08548596258"),
);
?>
up
5
Sbastien
4 years ago
Because of PHP comparaisons modalities, you can never distinguish null from others falsy values.
Note the absorbing nature of true and false booleans in mix types array.

<?php

$a = [true, false, null, '', '0', '123', 0, 123];
foreach (['SORT_REGULAR', 'SORT_NUMERIC', 'SORT_STRING', 'SORT_LOCALE_STRING'] as $flag) {
    $a_new = array_unique($a, constant($flag));
    echo "{$flag} ==> ";
    var_dump($a_new);
}

/*

Gives :

SORT_REGULAR ==> array(2) {
  [0]=> bool(true)
  [1]=> bool(false)
}
SORT_NUMERIC ==> array(3) {
  [0]=> bool(true)
  [1]=> bool(false)
  [5]=> string(3) "123"
}
SORT_STRING ==> array(4) {
  [0]=> bool(true)
  [1]=> bool(false)
  [4]=> string(1) "0"
  [5]=> string(3) "123"
}
SORT_LOCALE_STRING ==> array(4) {
  [0]=> bool(true)
  [1]=> bool(false)
  [4]=> string(1) "0"
  [5]=> string(3) "123"
}

*/
up
31
Mike D. - michal at euro-net.pl
3 years ago
modified code originally posted by Ghanshyam Katriya(anshkatriya at gmail) [highest voted comment here].

1. In php 7.4 counter $i breaks the function. Removed completely (imo was waste of keystrokes anyway).
2. I added second return value - array of duplicates. So you can take both and compare them (I had to).

Example array (copy-paste from original post):
<?php
$details = array(
    0 => array("id"=>"1", "name"=>"Mike",    "num"=>"9876543210"),
    1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
    2 => array("id"=>"1", "name"=>"Mathew",  "num"=>"784581254"),
);
?> 

Function:
<?php
function unique_multidim_array($array, $key) : array {
    $uniq_array = array();
    $dup_array = array();
    $key_array = array();

    foreach($array as $val) {
        if (!in_array($val[$key], $key_array)) {
            $key_array[] = $val[$key];
            $uniq_array[] = $val;
/*
            # 1st list to check:
            # echo "ID or sth: " . $val['building_id'] . "; Something else: " . $val['nodes_name'] . (...) "\n";
*/
        } else {
            $dup_array[] = $val;
/*
            # 2nd list to check:
            # echo "ID or sth: " . $val['building_id'] . "; Something else: " . $val['nodes_name'] . (...) "\n";
*/
        }
    }
    return array($uniq_array, $dup_array, /* $key_array */);
}
?> 

Usage:
<?php
list($unique_addresses, $duplicates, /* $unique_keys */) = unique_multidim_array($details,'id');
?>

Then:
var_dump($unique_addresses);
or
var_dump($duplicates);
or foreach or whatever. Personally I just echo-ed 1st and then 2nd (both DOUBLE COMMENTED) list in function itself (then copied both to notepad++ and compared them - just to be 100% sure), but in case you want to do something else with it - enjoy :)
Plus - as a bonus - you also get an array of UNIQUE keys you searched for (just uncomment >$key_array< in both: function return and function call code).

From example array code returns:
var_dump($unique_addresses); 
array(2) {
  [0]=>
  array(3) {
    ["id"]=>
    string(1) "1"
    ["name"]=>
    string(4) "Mike"
    ["num"]=>
    string(10) "9876543210"
  }
  [1]=>
  array(3) {
    ["id"]=>
    string(1) "2"
    ["name"]=>
    string(7) "Carissa"
    ["num"]=>
    string(11) "08548596258"
  }
}

var_dump($duplicates); 
array(1) {
  [0]=>
  array(3) {
    ["id"]=>
    string(1) "1"
    ["name"]=>
    string(6) "Mathew"
    ["num"]=>
    string(9) "784581254"
  }
}

Plus keys, if you want.

P.S.: in my - practical - case of DB querying I got around 4k uniques and 15k dupes :)
up
23
falundir at gmail dot com
8 years ago
I find it odd that there is no version of this function which allows you to use a comparator callable in order to determine items equality (like array_udiff and array_uintersect). So, here's my version for you:

<?php
function array_uunique(array $array, callable $comparator): array {
    $unique_array = [];
    do {
        $element = array_shift($array);
        $unique_array[] = $element;

        $array = array_udiff(
            $array,
            [$element],
            $comparator
        );
    } while (count($array) > 0);

    return $unique_array;
}
?>

And here is a test code:

<?php
class Foo {

    public $a;

    public function __construct(int $a) {
        $this->a = $a;
    }
}

$array_of_objects = [new Foo(2), new Foo(1), new Foo(3), new Foo(2), new Foo(2), new Foo(1)];

$comparator = function (Foo $foo1, Foo $foo2): int {
    return $foo1->a <=> $foo2->a;
};

var_dump(array_uunique($array_of_objects, $comparator)); // should output [Foo(2), Foo(1), Foo(3)]
?>
up
97
Anonymous
16 years ago
It's often faster to use a foreache and array_keys than array_unique:

    <?php

    $max = 1000000;
    $arr = range(1,$max,3);
    $arr2 = range(1,$max,2);
    $arr = array_merge($arr,$arr2);

    $time = -microtime(true);
    $res1 = array_unique($arr);
    $time += microtime(true);
    echo "deduped to ".count($res1)." in ".$time;
    // deduped to 666667 in 32.300781965256

    $time = -microtime(true);
    $res2 = array();
    foreach($arr