I was doing some sorting of Models in PHP. Unfortunately, I didn't have the luxury of letting the SQL do it all for me. Usually it does. But besides sorting, I had to make sure I didn't have any duplicate entries, since I was merging arrays with different queries. My first hope was PHP's array_unique method.
array_unique($array) will return an array with all duplicate values removed. What's deemed duplicate is when the string values are the same . This doesn't work for objects. I had used usort previously, so I looked for something similar like a uunique or something. No such luck.
I did find array_filter, which lets me specify a function the will determine what values get kept in the array and what gets ditched. So I created a simple dummy function, inside make a static array, grab the id from each model value in the array. I add the id to the static array, and then check the next value to see if the id has already been stored.
function unique_obj($obj) {
static $idList = array();
if(in_array($obj->id,$idList)) {
return false;
}
$idList []= $obj->id;
return true;
}
$posts = array_filter($posts,'unique_obj');

Just to make sure. You know about the "group by" part of SQL right? If you need unique combinations of fields, just use it in your query.
Yes I know SQL could have handled this for me, but I mentioned I wasn't able to in this case. I was in a place where I couldn't write a custom query, just use 2 pre-existing queries, and then merge them in PHP.
Your filter works fine as long as you want to filter just one array. For emulating the array_unique behavior, I would recommend analyzing the whole array.
My solution...
<?php foreach($arr as $obj) { if(!in_array((string) $obj,$list)) { $list = (string) $obj; $ret = $obj; } } $arr = $obj; return $arr; ?>But... Interesting piece of code. Is definitely much faster:)
@vlki & @Sean
The problem with using 'in_array' is that it is slow as sh*t !
in_array checks the whole array each call.
I prefer to use the id of each element as in:
$arr = array.. . $unique = array(); foreach( $arr as $k ) { if(!$unique[ $k['Id'] ]) { .. set it, do stuff.. } }@Tom Taylor: Good point about
in_array. It does check most of the array, until it finds 1 occurrence of the needle.I was trying to get the performance benefits of
array_filter, since that uses C code instead of interpreted PHP. I'm not sure which would perform better; a benchmark would determine what was indeed fastest, however, I doubt that would every be the bottleneck of an application.