Related
How can I remove duplicate values from an array in PHP?
Use array_unique().
Example:
$array = array(1, 2, 2, 3);
$array = array_unique($array); // Array is now (1, 2, 3)
Use array_values(array_unique($array));
array_unique: for unique array
array_values: for reindexing
//Find duplicates
$arr = array(
'unique',
'duplicate',
'distinct',
'justone',
'three3',
'duplicate',
'three3',
'three3',
'onlyone'
);
$unique = array_unique($arr);
$dupes = array_diff_key( $arr, $unique );
// array( 5=>'duplicate', 6=>'three3' 7=>'three3' )
// count duplicates
array_count_values($dupes); // array( 'duplicate'=>1, 'three3'=>2 )
$result = array();
foreach ($array as $key => $value){
if(!in_array($value, $result))
$result[$key]=$value;
}
The only thing which worked for me is:
$array = array_unique($array, SORT_REGULAR);
Edit : SORT_REGULAR keeps the same order of the original array.
sometimes array_unique() is not the way,
if you want get unique AND duplicated items...
$unique=array("","A1","","A2","","A1","");
$duplicated=array();
foreach($unique as $k=>$v) {
if( ($kt=array_search($v,$unique))!==false and $k!=$kt )
{ unset($unique[$kt]); $duplicated[]=$v; }
}
sort($unique); // optional
sort($duplicated); // optional
results on
array ( 0 => '', 1 => 'A1', 2 => 'A2', ) /* $unique */
array ( 0 => '', 1 => '', 2 => '', 3 => 'A1', ) /* $duplicated */
We can easily use arrar_unique($array); to remove duplicate elements
But the problem in this method is that the index of the elements are not in order, will cause problems if used somewhere else later.
Use
$arr = array_unique($arr);
$arr = array_values($arr);
print_r($arr);
Or
$arr = array_flip($arr);
$arr = array_flip($arr);
$arr = array_values($arr);
print_r($arr);
The first flip , flips the key value pair thus combines the elements with similar key(that was originally the value).
2nd flip to revert all the key value pairs. Finally array_value() sets each value with key starting from 0.
Note: Not to be used in associative array with predefined key value pairs
$a = array(1, 2, 3, 4);
$b = array(1, 6, 5, 2, 9);
$c = array_merge($a, $b);
$unique = array_keys(array_flip($c));
print_r($unique);
We can create such type of array to use this last value will be updated into column or key value and we will get unique value from the array...
$array = array (1,3,4,2,1,7,4,9,7,5,9);
$data=array();
foreach($array as $value ){
$data[$value]= $value;
}
array_keys($data);
OR
array_values($data);
explode(",", implode(",", array_unique(explode(",", $YOUR_ARRAY))));
This will take care of key associations and serialize the keys for the resulting new array :-)
Depending on the size of your array, I have found
$array = array_values( array_flip( array_flip( $array ) ) );
can be faster than array_unique.
There can be multiple ways to do these, which are as follows
//first method
$filter = array_map("unserialize", array_unique(array_map("serialize", $arr)));
//second method
$array = array_unique($arr, SORT_REGULAR);
If you concern in performance and have simple array, use:
array_keys(array_flip($array));
It's many times faster than array_unique.
This example is just an alternative.
<?php
$numbers = [1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,65776567567,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1];
$unique_numbers = [];
foreach($numbers as $number)
{
if(!in_array($number,$unique_numbers)){
$unique_numbers[] = $number;
}
}
print(json_encode($unique_numbers)); //// Array is now 1,3,4,5,6,2,7, ....
That's a great way to do it. Might want to make sure its output is back an array again. Now you're only showing the last unique value.
Try this:
$arrDuplicate = array ("","",1,3,"",5);
foreach (array_unique($arrDuplicate) as $v){
if($v != "") { $arrRemoved[] = $v; }
}
print_r ($arrRemoved);
if (#!in_array($classified->category,$arr)){
$arr[] = $classified->category;
?>
<?php } endwhile; wp_reset_query(); ?>
first time check value in array and found same value ignore it
Remove duplicate values from an associative array in PHP.
$arrDup = Array ('0' => 'aaa-aaa' , 'SKU' => 'aaa-aaa' , '1' => '12/1/1' , 'date' => '12/1/1' , '2' => '1.15' , 'cost' => '1.15' );
foreach($arrDup as $k => $v){
if(!( isset ($hold[$v])))
$hold[$v]=1;
else
unset($arrDup[$k]);
}
Array ( [0] => aaa-aaa [1] => 12/1/1 [2] => 1.15 )
$arrDuplicate = array ("","",1,3,"",5);
foreach(array_unique($arrDuplicate) as $v){
if($v != "" ){$arrRemoved = $v; }}
print_r($arrRemoved);
try this short & sweet code -
$array = array (1,4,2,1,7,4,9,7,5,9);
$unique = array();
foreach($array as $v){
isset($k[$v]) || ($k[$v]=1) && $unique[] = $v;
}
var_dump($unique);
Output -
array(6) {
[0]=>
int(1)
[1]=>
int(4)
[2]=>
int(2)
[3]=>
int(7)
[4]=>
int(9)
[5]=>
int(5)
}
<?php
$arr1 = [1,1,2,3,4,5,6,3,1,3,5,3,20];
print_r(arr_unique($arr1));
function arr_unique($arr) {
sort($arr);
$curr = $arr[0];
$uni_arr[] = $arr[0];
for($i=0; $i<count($arr);$i++){
if($curr != $arr[$i]) {
$uni_arr[] = $arr[$i];
$curr = $arr[$i];
}
}
return $uni_arr;
}
Here I've created a second empty array and used for loop with the first array which is having duplicates. It will run as many time as the count of the first array. Then compared with the position of the array with the first array and matched that it has this item already or not by using in_array. If not then it'll add that item to second array with array_push.
$a = array(1,2,3,1,3,4,5);
$count = count($a);
$b = [];
for($i=0; $i<$count; $i++){
if(!in_array($a[$i], $b)){
array_push($b, $a[$i]);
}
}
print_r ($b);
It can be done through function I made three function duplicate returns the values which are duplicate in array.
Second function single return only those values which are single mean not repeated in array and third and full function return all values but not duplicated if any value is duplicated it convert it to single;
function duplicate($arr) {
$duplicate;
$count = array_count_values($arr);
foreach($arr as $key => $value) {
if ($count[$value] > 1) {
$duplicate[$value] = $value;
}
}
return $duplicate;
}
function single($arr) {
$single;
$count = array_count_values($arr);
foreach($arr as $key => $value) {
if ($count[$value] == 1) {
$single[$value] = $value;
}
}
return $single;
}
function full($arr, $arry) {
$full = $arr + $arry;
sort($full);
return $full;
}
An alternative for array_unique() function..
Using Brute force algorithm
//[1] This our array with duplicated items
$matches = ["jorge","melvin","chelsy","melvin","jorge","smith"];
//[2] Container for the new array without any duplicated items
$arr = [];
//[3] get the length of the duplicated array and set it to the var len to be use for for loop
$len = count($matches);
//[4] If matches array key($i) current loop Iteration is not available in
//[4] the array $arr then push the current iteration key value of the matches[$i]
//[4] to the array arr.
for($i=0;$i
if(array_search($matches[$i], $arr) === false){
array_push($arr,$matches[$i]);
}
}
//print the array $arr.
print_r($arr);
//Result: Array
(
[0] => jorge
[1] => melvin
[2] => chelsy
[3] => smith
)
<?php
$a=array("1"=>"302","2"=>"302","3"=>"276","4"=>"301","5"=>"302");
print_r(array_values(array_unique($a)));
?>//`output -> Array ( [0] => 302 [1] => 276 [2] => 301 )`
I have done this without using any function.
$arr = array("1", "2", "3", "4", "5", "4", "2", "1");
$len = count($arr);
for ($i = 0; $i < $len; $i++) {
$temp = $arr[$i];
$j = $i;
for ($k = 0; $k < $len; $k++) {
if ($k != $j) {
if ($temp == $arr[$k]) {
echo $temp."<br>";
$arr[$k]=" ";
}
}
}
}
for ($i = 0; $i < $len; $i++) {
echo $arr[$i] . " <br><br>";
}
$array = array("a" => "moon", "star", "b" => "moon", "star", "sky");
// Deleting the duplicate items
$result = array_unique($array);
print_r($result);
ref : Demo
Is there a simpler way to get all array keys that has same value, when the value is unknown.
The problem with array_unique is that it returns the unique array and thus it doesn't find unique values.
That is, for example, from this array:
Array (
[a]=>1000
[b]=>1
[c]=>1000
)
I want to get this
Array (
[a]=>1000
[c]=>1000
)
Another way around this is, if I could find the lonely values, and then their keys, and then use array_diff
This is what I've got so far, looks awful:
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 );
$b = array_flip( array_count_values( $a ) );
krsort( $b );
$final = array_keys( $a, array_shift( $b ) );
Update
Using Paulo Freites' answer as a code base, I could get it working pretty easily, maintainable and easy on eyes kind of way… by using the filtering as a static class method I can get the duplicate values from an array by just calling ClassName::get_duplicates($array_to_filter)
private static $counts = null;
private static function filter_duplicates ($value) {
return self::$counts[ $value ] > 1;
}
public static function get_duplicates ($array) {
self::$counts = array_count_values( $array );
return array_filter( $array, 'ClassName::filter_duplicates' );
}
Taking advantage of closures for a more straightforward solution:
$array = array('a' => 1000, 'b' => 1, 'c' => 1000);
$counts = array_count_values($array);
$filtered = array_filter($array, function ($value) use ($counts) {
return $counts[$value] > 1;
});
var_dump($filtered);
This gave me the following:
array(2) {
["a"]=>
int(1000)
["c"]=>
int(1000)
}
Demo: https://eval.in/67526
That's all! :)
Update: backward-compatible solution
$array = array('a' => 1000, 'b' => 1, 'c' => 1000);
$counts = array_count_values($array);
$filtered = array_filter($array, create_function('$value',
'global $counts; return $counts[$value] > 1;'));
var_dump($filtered);
Demo: https://eval.in/68255
Your implementation has a few issues.
1) If there are 2 of value 1000 and 2 of another value, the array_flip will lose one of the sets of values.
2) If there are more than two different values, the array_keys will only find the one value that occurs most.
3) If there are no duplicates, you will still bring back one of the values.
Something like this works always and will return all duplicate values:
<?php
//the array
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 );
//count of values
$cnt = array_count_values($a);
//a new array
$newArray = array();
//loop over existing array
foreach($a as $k=>$v){
//if the count for this value is more than 1 (meaning value has a duplicate)
if($cnt[$v] > 1){
//add to the new array
$newArray[$k] = $v;
}
}
print_r($newArray);
http://codepad.viper-7.com/fal5Yz
If you want to get the duplicates in an array try this:
array_unique(array_diff_assoc($array1, array_unique($array1)))
I found this from:
http://www.php.net/manual/en/function.array-unique.php#95203
at the moment I cant figure out another solution...
// target array
$your_array = array('a'=>1000, 'b'=>1, 'c'=>1000);
// function to do all the job
function get_duplicate_elements($array) {
$res = array();
$counts = array_count_values($array);
foreach ($counts as $id=>$count) {
if ($count > 1) {
$r = array();
$keys = array_keys($array, $id);
foreach ($keys as $k) $r[$k] = $id;
$res[] = $r;
}
}
return sizeof($res) > 0 ? $res : false;
}
// test it
print_r(get_duplicate_elements($your_array));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
)
example #2: - when you have different values multiplied
// target array
$your_array = array('a'=>1000, 'b'=>1, 'c'=>1000, 'd'=>500, 'e'=>1);
// output
print_r(get_duplicate_elements($your_array));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
[1] => Array
(
[b] => 1
[e] => 1
)
)
if function result has been assigned to $res variable $res[0] gets an array of all elements from original array with first value found more than once, $res[1] gets array of elements with another duplicated-value, etc... function returns false if nothing duplicate has been found in argument-array.
Try this
$a = array( 'a' => 1, 'b' => 1000, 'c' => 1000,'d'=>'duplicate','e'=>'duplicate','f'=>'ok','g'=>'ok' );
$b = array_map("unserialize", array_unique(array_map("serialize", $a)));
$c = array_diff_key($a, $b);
$array = array("1"=>"A","2"=>"A","3"=>"A","4"=>"B","5"=>"B","6"=>"B");
$val = array_unique(array_values($array));
foreach ($val As $v){
$dat[$v] = array_keys($array,$v);
}
print_r($dat);
Here is my precode...
$keys = array('a', 'b', 'c', 'd');
$number = 10;
And here is my code...
eval('$array[\''.implode('\'][\'',$keys).'\'] = $number;');
Using this, I get the following result...
Array (
[a] => Array
(
[b] => Array
(
[c] => Array
(
[d] => 10
)
)
)
)
Now, the problem is that this is the exact result I want, but I don't want to use eval().
As input to my code, I have a list of keys and a number. The number should be set to the value of the keys array being used to generate child-based keys for a certain array $array.
Is there a different way that I can achieve this? I don't want to overwrite the keys/numbers with new values as the code works - eval() preserves this already, so my new code should do the same.
Please note that the code below (which you evaluate) will generate a warning, and will therefore not work on projects with error reporting up to the max:
$array = array();
$array['a']['b'] = 42; // $array['a'] is not an array... yet
Since you're using PHP 5, you can work with references to manipulate your array while traversing the branch of your tree that you wish to modify.
$current = & $array;
foreach ($keys as $key):
if (!isset($current[$key]) || !is_array($current[$key]))
$current[$key] = array();
$current = & $current[$key];
endforeach;
$current = $value;
Edit: corrected for avoiding warnings and conflicts.
Here is a full code example showing how it would work. Whats important is that you use a reference to the array so you can modify it:
<?php
$keys = array('a', 'b', 'c', 'd');
$number = 10;
$org_array = array(
"a" => "string",
"z" => array( "k" => false)
);
function write_to_array(&$array, $keys, $number){
$key = array_shift($keys);
if(!is_array($array[$key])) $array[$key] = array();
if(!empty($keys)){
write_to_array($array[$key], $keys, $number);
} else {
$array[$key] = $number;
}
}
write_to_array($org_array, $keys, $number);
print_r($org_array);
?>
function deepmagic($levels, $value)
{
if(count($levels) > 0)
{
return array($levels[0] => deepmagic(array_slice($levels, 1),
$value));
}
else
{
return $value;
}
}
$a = deepmagic(Array('a', 'b', 'c', 'd'), 10);
var_dump($a);
Output:
array(1) {
["a"]=>
array(1) {
["b"]=>
array(1) {
["c"]=>
array(1) {
["d"]=>
int(10)
}
}
}
}
How would you flip 90 degrees (transpose) a multidimensional array in PHP? For example:
// Start with this array
$foo = array(
'a' => array(
1 => 'a1',
2 => 'a2',
3 => 'a3'
),
'b' => array(
1 => 'b1',
2 => 'b2',
3 => 'b3'
),
'c' => array(
1 => 'c1',
2 => 'c2',
3 => 'c3'
)
);
$bar = flipDiagonally($foo); // Mystery function
var_dump($bar[2]);
// Desired output:
array(3) {
["a"]=>
string(2) "a2"
["b"]=>
string(2) "b2"
["c"]=>
string(2) "c2"
}
How would you implement flipDiagonally()?
Edit: this is not homework. I just want to see if any SOers have a more creative solution than the most obvious route. But since a few people have complained about this problem being too easy, what about a more general solution that works with an nth dimension array?
i.e. How would you write a function so that:
$foo[j][k][...][x][y][z] = $bar[z][k][...][x][y][j]
?(ps. I don't think 12 nested for loops is the best solution in this case.)
function transpose($array) {
array_unshift($array, null);
return call_user_func_array('array_map', $array);
}
Or if you're using PHP 5.6 or later:
function transpose($array) {
return array_map(null, ...$array);
}
With 2 loops.
function flipDiagonally($arr) {
$out = array();
foreach ($arr as $key => $subarr) {
foreach ($subarr as $subkey => $subvalue) {
$out[$subkey][$key] = $subvalue;
}
}
return $out;
}
I think you're referring to the array transpose (columns become rows, rows become columns).
Here is a function that does it for you (source):
function array_transpose($array, $selectKey = false) {
if (!is_array($array)) return false;
$return = array();
foreach($array as $key => $value) {
if (!is_array($value)) return $array;
if ($selectKey) {
if (isset($value[$selectKey])) $return[] = $value[$selectKey];
} else {
foreach ($value as $key2 => $value2) {
$return[$key2][$key] = $value2;
}
}
}
return $return;
}
Transposing an N-dimensional array:
function transpose($array, &$out, $indices = array())
{
if (is_array($array))
{
foreach ($array as $key => $val)
{
//push onto the stack of indices
$temp = $indices;
$temp[] = $key;
transpose($val, $out, $temp);
}
}
else
{
//go through the stack in reverse - make the new array
$ref = &$out;
foreach (array_reverse($indices) as $idx)
$ref = &$ref[$idx];
$ref = $array;
}
}
$foo[1][2][3][3][3] = 'a';
$foo[4][5][6][5][5] = 'b';
$out = array();
transpose($foo, $out);
echo $out[3][3][3][2][1] . ' ' . $out[5][5][6][5][4];
Really hackish, and probably not the best solution, but hey it works.
Basically it traverses the array recursively, accumulating the current indicies in an array.
Once it gets to the referenced value, it takes the "stack" of indices and reverses it, putting it into the $out array. (Is there a way of avoiding use of the $temp array?)
Codler's answer fails for a single-row matrix (e.g. [[1,2]]) and also for the empty matrix ([]), which must be special-cased:
function transpose(array $matrix): array {
if (!$matrix) return [];
return array_map(count($matrix) == 1 ? fn ($x) => [$x] : null, ...$matrix);
}
(note: PHP 7.4+ syntax, easy enough to adapt for older versions)
I got confronted with the same problem. Here is what i came up with:
function array_transpose(array $arr)
{
$keys = array_keys($arr);
$sum = array_values(array_map('count', $arr));
$transposed = array();
for ($i = 0; $i < max($sum); $i ++)
{
$item = array();
foreach ($keys as $key)
{
$item[$key] = array_key_exists($i, $arr[$key]) ? $arr[$key][$i] : NULL;
}
$transposed[] = $item;
}
return $transposed;
}
I needed a transpose function with support for associative array:
$matrix = [
['one' => 1, 'two' => 2],
['one' => 11, 'two' => 22],
['one' => 111, 'two' => 222],
];
$result = \array_transpose($matrix);
$trans = [
'one' => [1, 11, 111],
'two' => [2, 22, 222],
];
And the way back:
$matrix = [
'one' => [1, 11, 111],
'two' => [2, 22, 222],
];
$result = \array_transpose($matrix);
$trans = [
['one' => 1, 'two' => 2],
['one' => 11, 'two' => 22],
['one' => 111, 'two' => 222],
];
The array_unshift trick did not work NOR the array_map...
So I've coded a array_map_join_array function to deal with record keys association:
/**
* Similar to array_map() but tries to join values on intern keys.
* #param callable $callback takes 2 args, the intern key and the list of associated values keyed by array (extern) keys.
* #param array $arrays the list of arrays to map keyed by extern keys NB like call_user_func_array()
* #return array
*/
function array_map_join_array(callable $callback, array $arrays)
{
$keys = [];
// try to list all intern keys
array_walk($arrays, function ($array) use (&$keys) {
$keys = array_merge($keys, array_keys($array));
});
$keys = array_unique($keys);
$res = [];
// for each intern key
foreach ($keys as $key) {
$items = [];
// walk through each array
array_walk($arrays, function ($array, $arrKey) use ($key, &$items) {
if (isset($array[$key])) {
// stack/transpose existing value for intern key with the array (extern) key
$items[$arrKey] = $array[$key];
} else {
// or stack a null value with the array (extern) key
$items[$arrKey] = null;
}
});
// call the callback with intern key and all the associated values keyed with array (extern) keys
$res[$key] = call_user_func($callback, $key, $items);
}
return $res;
}
and array_transpose became obvious:
function array_transpose(array $matrix)
{
return \array_map_join_array(function ($key, $items) {
return $items;
}, $matrix);
}
We can do this by using Two foreach. Traveling one array and another array to create new arrayLike This:
$foo = array(
'a' => array(
1 => 'a1',
2 => 'a2',
3 => 'a3'
),
'b' => array(
1 => 'b1',
2 => 'b2',
3 => 'b3'
),
'c' => array(
1 => 'c1',
2 => 'c2',
3 => 'c3'
)
);
$newFoo = [];
foreach($foo as $a => $k){
foreach($k as $i => $j){
$newFoo[$i][]= $j;
}
}
Check The Output
echo "<pre>";
print_r($newFoo);
echo "</pre>";
Before I start, I'd like to say thanks again to #quazardus for posting his generalised solution for tranposing any two dimenional associative (or non-associative) array!
As I am in the habit of writing my code as tersely as possible I went on to "minimizing" his code a little further. This will very likely not be to everybody's taste. But just in case anyone should be interested, here is my take on his solution:
function arrayMap($cb, array $arrays) // $cb: optional callback function
{ $keys = [];
array_walk($arrays, function ($array) use (&$keys)
{ $keys = array_merge($keys, array_keys($array)); });
$keys = array_unique($keys); $res = [];
foreach ($keys as $key) {
$items = array_map(function ($arr) use ($key)
{return isset($arr[$key]) ? $arr[$key] : null; },$arrays);
$res[$key] = call_user_func(
is_callable($cb) ? $cb
: function($k, $itms){return $itms;},
$key, $items);
}
return $res;
}
Now, analogous to the PHP standard function array_map(), when you call
arrayMap(null,$b);
you will get the desired transposed matrix.
This is another way to do the exact same thing which #codler s answer does. I had to dump some arrays in csv so I used the following function:
function transposeCsvData($data)
{
$ct=0;
foreach($data as $key => $val)
{
//echo count($val);
if($ct< count($val))
$ct=count($val);
}
//echo $ct;
$blank=array_fill(0,$ct,array_fill(0,count($data),null));
//print_r($blank);
$retData = array();
foreach ($data as $row => $columns)
{
foreach ($columns as $row2 => $column2)
{
$retData[$row2][$row] = $column2;
}
}
$final=array();
foreach($retData as $k=>$aval)
{
$final[]=array_replace($blank[$k], $aval);
}
return $final;
}
Test and output reference: https://tutes.in/how-to-transpose-an-array-in-php-with-irregular-subarray-size/
Here is array_walk way to achieve this,
function flipDiagonally($foo){
$temp = [];
array_walk($foo, function($item,$key) use(&$temp){
foreach($item as $k => $v){
$temp[$k][$key] = $v;
}
});
return $temp;
}
$bar = flipDiagonally($foo); // Mystery function
Demo.
Here's a variation of Codler/Andreas's solution that works with associative arrays. Somewhat longer but loop-less purely functional:
<?php
function transpose($array) {
$keys = array_keys($array);
return array_map(function($array) use ($keys) {
return array_combine($keys, $array);
}, array_map(null, ...array_values($array)));
}
Example:
<?php
$foo = array(
"fooA" => [ "a1", "a2", "a3"],
"fooB" => [ "b1", "b2", "b3"],
"fooC" => [ "c1", "c2", "c3"]
);
print_r( transpose( $foo ));
// Output like this:
Array (
[0] => Array (
[fooA] => a1
[fooB] => b1
[fooC] => c1
)
[1] => Array (
[fooA] => a2
[fooB] => b2
[fooC] => c2
)
[2] => Array (
[fooA] => a3
[fooB] => b3
[fooC] => c3
)
);
How can I remove duplicate values from an array in PHP?
Use array_unique().
Example:
$array = array(1, 2, 2, 3);
$array = array_unique($array); // Array is now (1, 2, 3)
Use array_values(array_unique($array));
array_unique: for unique array
array_values: for reindexing
//Find duplicates
$arr = array(
'unique',
'duplicate',
'distinct',
'justone',
'three3',
'duplicate',
'three3',
'three3',
'onlyone'
);
$unique = array_unique($arr);
$dupes = array_diff_key( $arr, $unique );
// array( 5=>'duplicate', 6=>'three3' 7=>'three3' )
// count duplicates
array_count_values($dupes); // array( 'duplicate'=>1, 'three3'=>2 )
$result = array();
foreach ($array as $key => $value){
if(!in_array($value, $result))
$result[$key]=$value;
}
The only thing which worked for me is:
$array = array_unique($array, SORT_REGULAR);
Edit : SORT_REGULAR keeps the same order of the original array.
sometimes array_unique() is not the way,
if you want get unique AND duplicated items...
$unique=array("","A1","","A2","","A1","");
$duplicated=array();
foreach($unique as $k=>$v) {
if( ($kt=array_search($v,$unique))!==false and $k!=$kt )
{ unset($unique[$kt]); $duplicated[]=$v; }
}
sort($unique); // optional
sort($duplicated); // optional
results on
array ( 0 => '', 1 => 'A1', 2 => 'A2', ) /* $unique */
array ( 0 => '', 1 => '', 2 => '', 3 => 'A1', ) /* $duplicated */
We can easily use arrar_unique($array); to remove duplicate elements
But the problem in this method is that the index of the elements are not in order, will cause problems if used somewhere else later.
Use
$arr = array_unique($arr);
$arr = array_values($arr);
print_r($arr);
Or
$arr = array_flip($arr);
$arr = array_flip($arr);
$arr = array_values($arr);
print_r($arr);
The first flip , flips the key value pair thus combines the elements with similar key(that was originally the value).
2nd flip to revert all the key value pairs. Finally array_value() sets each value with key starting from 0.
Note: Not to be used in associative array with predefined key value pairs
$a = array(1, 2, 3, 4);
$b = array(1, 6, 5, 2, 9);
$c = array_merge($a, $b);
$unique = array_keys(array_flip($c));
print_r($unique);
We can create such type of array to use this last value will be updated into column or key value and we will get unique value from the array...
$array = array (1,3,4,2,1,7,4,9,7,5,9);
$data=array();
foreach($array as $value ){
$data[$value]= $value;
}
array_keys($data);
OR
array_values($data);
explode(",", implode(",", array_unique(explode(",", $YOUR_ARRAY))));
This will take care of key associations and serialize the keys for the resulting new array :-)
Depending on the size of your array, I have found
$array = array_values( array_flip( array_flip( $array ) ) );
can be faster than array_unique.
There can be multiple ways to do these, which are as follows
//first method
$filter = array_map("unserialize", array_unique(array_map("serialize", $arr)));
//second method
$array = array_unique($arr, SORT_REGULAR);
If you concern in performance and have simple array, use:
array_keys(array_flip($array));
It's many times faster than array_unique.
This example is just an alternative.
<?php
$numbers = [1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,65776567567,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1,1,3,4,5,6,2,5,7,1];
$unique_numbers = [];
foreach($numbers as $number)
{
if(!in_array($number,$unique_numbers)){
$unique_numbers[] = $number;
}
}
print(json_encode($unique_numbers)); //// Array is now 1,3,4,5,6,2,7, ....
That's a great way to do it. Might want to make sure its output is back an array again. Now you're only showing the last unique value.
Try this:
$arrDuplicate = array ("","",1,3,"",5);
foreach (array_unique($arrDuplicate) as $v){
if($v != "") { $arrRemoved[] = $v; }
}
print_r ($arrRemoved);
if (#!in_array($classified->category,$arr)){
$arr[] = $classified->category;
?>
<?php } endwhile; wp_reset_query(); ?>
first time check value in array and found same value ignore it
Remove duplicate values from an associative array in PHP.
$arrDup = Array ('0' => 'aaa-aaa' , 'SKU' => 'aaa-aaa' , '1' => '12/1/1' , 'date' => '12/1/1' , '2' => '1.15' , 'cost' => '1.15' );
foreach($arrDup as $k => $v){
if(!( isset ($hold[$v])))
$hold[$v]=1;
else
unset($arrDup[$k]);
}
Array ( [0] => aaa-aaa [1] => 12/1/1 [2] => 1.15 )
$arrDuplicate = array ("","",1,3,"",5);
foreach(array_unique($arrDuplicate) as $v){
if($v != "" ){$arrRemoved = $v; }}
print_r($arrRemoved);
try this short & sweet code -
$array = array (1,4,2,1,7,4,9,7,5,9);
$unique = array();
foreach($array as $v){
isset($k[$v]) || ($k[$v]=1) && $unique[] = $v;
}
var_dump($unique);
Output -
array(6) {
[0]=>
int(1)
[1]=>
int(4)
[2]=>
int(2)
[3]=>
int(7)
[4]=>
int(9)
[5]=>
int(5)
}
<?php
$arr1 = [1,1,2,3,4,5,6,3,1,3,5,3,20];
print_r(arr_unique($arr1));
function arr_unique($arr) {
sort($arr);
$curr = $arr[0];
$uni_arr[] = $arr[0];
for($i=0; $i<count($arr);$i++){
if($curr != $arr[$i]) {
$uni_arr[] = $arr[$i];
$curr = $arr[$i];
}
}
return $uni_arr;
}
Here I've created a second empty array and used for loop with the first array which is having duplicates. It will run as many time as the count of the first array. Then compared with the position of the array with the first array and matched that it has this item already or not by using in_array. If not then it'll add that item to second array with array_push.
$a = array(1,2,3,1,3,4,5);
$count = count($a);
$b = [];
for($i=0; $i<$count; $i++){
if(!in_array($a[$i], $b)){
array_push($b, $a[$i]);
}
}
print_r ($b);
It can be done through function I made three function duplicate returns the values which are duplicate in array.
Second function single return only those values which are single mean not repeated in array and third and full function return all values but not duplicated if any value is duplicated it convert it to single;
function duplicate($arr) {
$duplicate;
$count = array_count_values($arr);
foreach($arr as $key => $value) {
if ($count[$value] > 1) {
$duplicate[$value] = $value;
}
}
return $duplicate;
}
function single($arr) {
$single;
$count = array_count_values($arr);
foreach($arr as $key => $value) {
if ($count[$value] == 1) {
$single[$value] = $value;
}
}
return $single;
}
function full($arr, $arry) {
$full = $arr + $arry;
sort($full);
return $full;
}
As an alternative of array_unique() you may use php Set class
$array = array(1, 2, 2, 3);
$array = (new \Ds\Set($array))->toArray() ; // Array is now (1, 2, 3)
An alternative for array_unique() function..
Using Brute force algorithm
//[1] This our array with duplicated items
$matches = ["jorge","melvin","chelsy","melvin","jorge","smith"];
//[2] Container for the new array without any duplicated items
$arr = [];
//[3] get the length of the duplicated array and set it to the var len to be use for for loop
$len = count($matches);
//[4] If matches array key($i) current loop Iteration is not available in
//[4] the array $arr then push the current iteration key value of the matches[$i]
//[4] to the array arr.
for($i=0;$i
if(array_search($matches[$i], $arr) === false){
array_push($arr,$matches[$i]);
}
}
//print the array $arr.
print_r($arr);
//Result: Array
(
[0] => jorge
[1] => melvin
[2] => chelsy
[3] => smith
)
<?php
$a=array("1"=>"302","2"=>"302","3"=>"276","4"=>"301","5"=>"302");
print_r(array_values(array_unique($a)));
?>//`output -> Array ( [0] => 302 [1] => 276 [2] => 301 )`
I have done this without using any function.
$arr = array("1", "2", "3", "4", "5", "4", "2", "1");
$len = count($arr);
for ($i = 0; $i < $len; $i++) {
$temp = $arr[$i];
$j = $i;
for ($k = 0; $k < $len; $k++) {
if ($k != $j) {
if ($temp == $arr[$k]) {
echo $temp."<br>";
$arr[$k]=" ";
}
}
}
}
for ($i = 0; $i < $len; $i++) {
echo $arr[$i] . " <br><br>";
}
$array = array("a" => "moon", "star", "b" => "moon", "star", "sky");
// Deleting the duplicate items
$result = array_unique($array);
print_r($result);
ref : Demo