I have this following array :
Array
(
[1] => Array
(
[0] => 2013-07
[1] => 4
[2] => 4
[3] => 3060
[4] => 1
)
[2] => Array
(
[0] => 2013-07
[1] => 270
[2] => 757
[3] => 13812810
[4] => 4
)
And i want to delete all the duplicated elements and replace $month[1][4] with it sum:
$result = array_reduce($month, function($cur, $x)
{
return $cur + $x[4];
}, 0);
$month = array_unique($month); //<---- Exception
$month[1][4]=$result;
It works fine but it displays me this exception Notice: Array to string conversion !
How can I prevent this from happening?
Thanks
Quick Answer: use:
$unique = array_unique($a, SORT_REGULAR);
// OR
$unique = array_map('unserialize', array_unique(array_map('serialize', $a)));
Explanation
The problem comes about because you're using a multi-dimensional array, array_unique() uses using string conversion before comparing the values to find the unique values:
Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same. The first element will be used.
An array will always convert to "Array" when casting it to a string:
var_dump("Array" === (string) array());
You can solve this by specifying the SORT_REGULAR mode in the second parameter of array_unique:
$unique = array_unique($a, SORT_REGULAR);
Or, if that doesn’t work, by serializing the arrays before and unserializing it after calling array_unique to find the unique values:
$unique = array_map('unserialize', array_unique(array_map('serialize', $a)));
This is what you need:
$month= array_unique($month, SORT_REGULAR);
Related
I have an array like this:
$arr = array ( [0] => array("red","green"),
[1] => array("blue","yellow")
);
And this is expected result:
Array ( [0] => red [1] => green [2] => blue [3] => yellow )
See? I want to merge all items of $arr (which are also array themselves). How can I do that?
I can do a loop on it and then use array_merge() every time like this:
$res = [];
foreach ( $arr as $item ) {
$res = array_merge($res, $item);
}
It works as well. But I guess I can write it better. Any idea?
You can do trick with call_user_func_array:
$result = call_user_func_array('array_merge', $arr);
This trick is possible, because array_merge accept dynamic arguments count.
It's a style exercise, but if the structure remains the same as in your example, you can play with this:
$arr = array ( '0' => array("red","green"),
'1' => array("blue","yellow")
);
$res = explode(",",str_replace(array('[',']'),'',json_encode($arr)));
Hope this helps.
You declare array in wrong way:
$arr = array ( 0 => array("red","green"),
1 => array("blue","yellow")
);
The error reported by PHP says it clearly:
Fatal error: Illegal offset type in /in/Hhfqa on line 3
Line 3 in your example is exactly line of first array element.
Please check http://php.net/manual/en/language.types.array.php
$result = array(
0=>array('a'=>1,'b'=>'Hello'),
1=>array('a'=>1,'b'=>'other'),
2=>array('a'=>1,'b'=>'other'),
);
If it is duplicated removed it, so the result is as follows:
$result = array(
0=>array('a'=>1,'b'=>'Hello'),
1=>array('a'=>1,'b'=>'other')
);
Could any know to do this?
Thanks
Regardless what others are offering here, you are looking for a function called array_uniqueDocs. The important thing here is to set the second parameter to SORT_REGULAR and then the job is easy:
array_unique($result, SORT_REGULAR);
The meaning of the SORT_REGULAR flag is:
compare items normally (don't change types)
And that is what you want. You want to compare arraysDocs here and do not change their type to string (which would have been the default if the parameter is not set).
array_unique does a strict comparison (=== in PHP), for arrays this means:
$a === $b TRUE if $a and $b have the same key/value pairs in the same order and of the same types.
Output (Demo):
Array
(
[0] => Array
(
[a] => 1
[b] => Hello
)
[1] => Array
(
[a] => 1
[b] => other
)
)
First things first, you can not use plain array_unique for this problem because array_unique internally treats the array items as strings, which is why "Cannot convert Array to String" notices will appear when using array_unique for this.
So try this:
$result = array(
0=>array('a'=>1,'b'=>'Hello'),
1=>array('a'=>1,'b'=>'other'),
2=>array('a'=>1,'b'=>'other')
);
$unique = array_map("unserialize", array_unique(array_map("serialize", $result)));
print_r($unique);
Result:
Array
(
[0] => Array
(
[a] => 1
[b] => Hello
)
[1] => Array
(
[a] => 1
[b] => other
)
)
Serialization is very handy for such problems.
If you feel that's too much magic for you, check out this blog post
function array_multi_unique($multiArray){
$uniqueArray = array();
foreach($multiArray as $subArray){
if(!in_array($subArray, $uniqueArray)){
$uniqueArray[] = $subArray;
}
}
return $uniqueArray;
}
$unique = array_multi_unique($result);
print_r($unique);
Ironically, in_array is working for arrays, where array_unique does not.
is there a built in function in php that prepends an element to an array, and returns the new array?
instead of returning the new length of the array?
You could use
array_merge()
For example
$resultingArray = array_merge(array($newElement), $originalArray);
Next to array_merge, if there ain't any duplicate keys, you can do:
$array = array('a' => 'A');
$append = array('b' => 'hello');
$array = $append + $array;
Gives:
Array
(
[b] => hello
[a] => A
)
The plus is the array union operatorÂDocs.
There's no built-in which does it, but it's simple enough to wrap it:
function my_unshift($array, $var) {
array_unshift($array, $var);
return $array;
}
This isn't necessary though, because array_unshift() operates on an array reference so the original is modified in place. array_push(), array_pop(), array_shift() all also operate on a a reference.
$arr = array(1,2,3);
array_unshift($arr, 0);
// No need for return. $arr has been modified
print_arr($arr);
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
)
I'm new to working with arrays so I need some help. With getting just one vaule from an array. I have an original array that looks like this:
$array1= Array(
[0] => 1_31
[1] => 1_65
[2] => 29_885...)
What I'm trying to do is seach for and return just the value after the underscore. I've figured out how to get that data into a second array and return the vaules as a new array.
foreach($array1 as $key => $value){
$id = explode('_',$value);
}
which gives me:
Array ( [0] => 1 [1] => 31 )
Array ( [0] => 1 [1] => 65 )
Array ( [0] => 29 [1] => 885 )
I can also get a list of the id's or part after the underscore by using $id[1] I'm just not sure if this is the best way and if it is how to do a search. I've tried using in_array() but that searches the whole array and I couldn't make it just search one key of the array.
Any help would be great.
If the part after underscore is unique, make it a key for new array:
$newArray = array();
foreach($array1 as $key => $value){
list($v,$k) = explode('_',$value);
$newArray[$k] = $v;
}
So you can check for key existence with isset($newArray[$mykey]), which will be more efficient.
You can use preg_grep() to grep an array:
$array1= array("1_31", "1_65", "29_885");
$num = 65;
print_r(preg_grep("/^\d+_$num$/", $array1));
Outputs:
Array
(
[1] => 1_65
)
See http://ideone.com/3Fgr8
I would say you're doing it just about as well as anyone else would.
EDIT
Alternate method:
$array1 = array_map(create_function('$a','$_ = explode("_",$a); return $_[1];'),$array1);
echo in_array(3,$array1) ? "yes" : "no"; // 3 being the example
I would have to agree. If you wish to see is a value exists in an array however just use the 'array_key_exists' function, if it returns true use the value for whatever.
I have an array in PHP and I want to remove duplicates.
I simply turned to the function array_unique() to create a new array and remove the duplicates.
Here's the code:
$unlink = array();
$unlink = array_unique($linkphoto);
foreach ($unlink as $link) {
echo $link, "<br />";
}
Still it shows duplicates! Any suggestions about what's wrong?
According to the documentation, the condition for equality is as follows:
Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same. The first element will be used.
What sort of data are you using? If two items aren't string equal, then they'll both remain in the array.
We need more context in order to be able to help you, like what the contents are of $linkphoto before array_unique is applied to it. For example:
<?php
$array = Array('A','B','C','D','B');
print_r($array); // Array ( [0] => A [1] => B [2] => C [3] => D [4] => B )
$result = array_unique($array);
print_r($result); // Array ( [0] => A [1] => B [2] => C [3] => D )
?>
As #nobody_ mentioned, it will only eliminate duplicates if their string representations are the same.