Php foreach array unique

array_unique

Takes an input array and returns a new array without duplicate values.

Note that keys are preserved. If multiple elements compare equal under the given flags , then the key and value of the first equal element will be retained.

Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2 i.e. when the string representation is the same, the first element will be used.

Parameters

The optional second parameter flags may be used to modify the comparison behavior using these values:

  • SORT_REGULAR — compare items normally (don’t change types)
  • SORT_NUMERIC — compare items numerically
  • SORT_STRING — compare items as strings
  • SORT_LOCALE_STRING — compare items as strings, based on the current locale.

Return Values

Returns the filtered array.

Changelog

Version Description
7.2.0 If flags is SORT_STRING , formerly array has been copied and non-unique elements have been removed (without packing the array afterwards), but now a new array is built by adding the unique elements. This can result in different numeric indexes.

Examples

Example #1 array_unique() example

$input = array( «a» => «green» , «red» , «b» => «green» , «blue» , «red» );
$result = array_unique ( $input );
print_r ( $result );
?>

The above example will output:

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

Example #2 array_unique() and types

$input = array( 4 , «4» , «3» , 4 , 3 , «3» );
$result = array_unique ( $input );
var_dump ( $result );
?>

The above example will output:

Notes

Note: Note that array_unique() is not intended to work on multi dimensional arrays.

See Also

User Contributed Notes 32 notes

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,

$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 :
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,
$details = unique_multidim_array ( $details , ‘id’ );
?>

Output will be like this :
$details = array(
0 => array( «id» => «1» , «name» => «Mike» , «num» => «9876543210» ),
1 => array( «id» => «2» , «name» => «Carissa» , «num» => «08548596258» ),
);
?>

Читайте также:  Javascript windows open chrome

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):
$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:
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:
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»
>
>

P.S.: in my — practical — case of DB querying I got around 4k uniques and 15k dupes 🙂

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:

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:

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 ;
>;

Читайте также:  Тег TITLE

var_dump ( array_uunique ( $array_of_objects , $comparator )); // should output [Foo(2), Foo(1), Foo(3)]
?>

In reply to performance tests array_unique vs foreach.

In PHP7 there were significant changes to Packed and Immutable arrays resulting in the performance difference to drop considerably. Here is the same test on php7.1 here;
http://sandbox.onlinephpfunctions.com/code/2a9e986690ef8505490489581c1c0e70f20d26d1

$max = 770000; //large enough number within memory allocation
$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 513333 in 1.0876770019531

$time = -microtime(true);
$res2 = array();
foreach($arr as $key=>$val) <
$res2[$val] = true;
>
$res2 = array_keys($res2);
$time += microtime(true);
echo «
deduped to «.count($res2).» in «.$time;
// deduped to 513333 in 0.054931879043579

It’s often faster to use a foreache and array_keys than array_unique:

$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 as $key => $val ) <
$res2 [ $val ] = true ;
>
$res2 = array_keys ( $res2 );
$time += microtime ( true );
echo «
deduped to » . count ( $res2 ). » in » . $time ;
// deduped to 666667 in 0.84372591972351

I needed to identify email addresses in a data table that were replicated, so I wrote the array_not_unique() function:

function array_not_unique ( $raw_array ) $dupes = array();
natcasesort ( $raw_array );
reset ( $raw_array );

$old_key = NULL ;
$old_value = NULL ;
foreach ( $raw_array as $key => $value ) if ( $value === NULL ) < continue; >
if ( $old_value == $value ) $dupes [ $old_key ] = $old_value ;
$dupes [ $key ] = $value ;
>
$old_value = $value ;
$old_key = $key ;
>
return $dupes ;
>

$raw_array = array();
$raw_array [ 1 ] = ‘abc@xyz.com’ ;
$raw_array [ 2 ] = ‘def@xyz.com’ ;
$raw_array [ 3 ] = ‘ghi@xyz.com’ ;
$raw_array [ 4 ] = ‘abc@xyz.com’ ; // Duplicate

$common_stuff = array_not_unique ( $raw_array );
var_dump ( $common_stuff );
?>

Taking the advantage of array_unique, here is a simple function to check if an array has duplicate values.

It simply compares the number of elements between the original array and the array_uniqued array.

function array_has_duplicates (array $array )
<
$uniq = array_unique ( $array );
return count ( $uniq ) != count ( $array );
>

Case insensitive; will keep first encountered value.

function array_iunique ( $array ) <
$lowered = array_map ( ‘strtolower’ , $array );
return array_intersect_key ( $array , array_unique ( $lowered ));
>

As for PHP 7.1.12, this is the comparison between array_keys(array_flip()), array_flip(array_flip()), for each elimination and array_unique. The array_keys(array_flip()) is the fastest method to remove duplication values from a single dimension array:

$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 0.78185796737671
// memory used: 33558528

Читайте также:  Run html codes online

$time = — microtime ( true );
$res2 = array_flip ( array_flip ( $arr ));
$time += microtime ( true );

echo «

deduped to » . count ( $res2 ). » in » . $time ;
// deduped to 666667 in 0.072191953659058
// memory used: 3774873

$time = — microtime ( true );
$res3 = array();
foreach( $arr as $key => $val ) $res3 [ $val ] = true ;
>
$res3 = array_keys ( $res3 );
$time += microtime ( true );

echo «

deduped to » . count ( $res3 ). » in » . $time ;
// deduped to 666667 in 0.095494985580444
// memory used: 33558528

$time = — microtime ( true );
$res4 = array_keys ( array_flip ( $arr ));
$time += microtime ( true );

echo «

deduped to » . count ( $res4 ). » in » . $time ;
// deduped to 666667 in 0.05807900428772
// memory used: 33558528

Here is a solution to make unique values keeping empty values for an array with keys :

function array_unique_kempty ( $array ) $values = array_unique ( $array );
$return = array_combine ( array_keys ( $array ), array_fill ( 0 , count ( $array ), null ));
return array_merge ( $return , $values );
>

$myArray = [
«test1» => «aaa» ,
«test2» => null ,
«test3» => «aaa» ,
«test4» => «bbb» ,
«test5» => null ,
«test6» => «ccc» ,
«test7» => «ddd» ,
«test8» => «ccc»
];

echo «

" . print_r ( array_unique_kempty ( $myArray ), true ). "

» ;

Following the Ghanshyam Katriya idea, but with an array of objects, where the $key is related to object propriety that you want to filter the uniqueness of array:

recursive array unique for multiarrays

function super_unique ( $array )
$result = array_map ( «unserialize» , array_unique ( array_map ( «serialize» , $array )));

foreach ( $result as $key => $value )
if ( is_array ( $value ) )
$result [ $key ] = super_unique ( $value );
>
>

If you find the need to get a sorted array without it preserving the keys, use this code which has worked for me:

$array = array( «hello» , «fine» , «good» , «fine» , «hello» , «bye» );

$get_sorted_unique_array = array_values ( array_unique ( $array ));

?>

The above code returns an array which is both unique and sorted from zero.

My object unique function:

function object_unique ( $obj ) $objArray = (array) $obj ;

$objArray = array_intersect_assoc ( array_unique ( $objArray ), $objArray );

foreach( $obj as $n => $f ) if( ! array_key_exists ( $n , $objArray ) ) unset( $obj -> $n );
>

return $obj ;
>
?>

And these code:

class Test public $pr0 = ‘string’ ;
public $pr1 = ‘string1’ ;
public $pr2 = ‘string’ ;
public $pr3 = ‘string2’ ;
>

var_dump ( object_unique ( $obj ) );
?>

returns:
object(Test)[1]
public ‘pr0’ => string ‘string’ (length=6)
public ‘pr1’ => string ‘string1’ (length=7)
public ‘pr3’ => string ‘string2’ (length=7)

This is a script for multi_dimensional arrays

function remove_dup ( $matriz ) <
$aux_ini =array();
$entrega =array();
for( $n = 0 ; $n < count ( $matriz ); $n ++)
<
$aux_ini []= serialize ( $matriz [ $n ]);
>
$mat = array_unique ( $aux_ini );
for( $n = 0 ; $n < count ( $matriz ); $n ++)

$entrega []= unserialize ( $mat [ $n ]);

Источник

Оцените статью