Jade, in your foreach loop, $key is in the set {0, 1, 2} (or {1, 2, 3} depending on which post you look at). You must have misread the question. The input is an array of arrays. There ends up being one item in $newarray because integer 0 equals string 'id'.
Doug, here are some solutions I cooked up.
The first is the simplest, but does not preserve the original keys. Instead, the ids become the keys. Because keys of an array are unique, this is a simple way to ensure the array contains no duplicate records. Existing records just get overwritten with (hopefully) identical data.
Code: Select all
$uniqueRecords = array();
foreach ($records as $record) {
$uniqueRecords[$record['id']] = $record;
}
You can use array_values() to make the keys sequential and start at zero again, but that still won't restore the original keys.
If you want to maintain the original keys, you can use array_filter(). This example uses an anonymous (lambda/closure) function. It uses a static variable (maintained between function calls) to collect ids as they are discovered and compares the current id with the array of known ids to determine if the current record is a duplicate.
Code: Select all
$uniqueRecords = array_filter($records, function($record){
static $ids = array();
$isUnique = !in_array($record['id'], $ids);
if ($isUnique) {
$ids[] = $record['id'];
}
return $isUnique;
});
Here is a variant of the same, except that the ids are stored in the keys of the $ids array. I expect it to be more efficient (though I haven't tested it).
Code: Select all
$uniqueRecords = array_filter($records, function($record){
static $ids = array();
$isUnique = !isset($ids[$record['id']]);
if ($isUnique) {
$ids[$record['id']] = true;
}
return $isUnique;
});
If you like code that is clever but difficult to read, this example does the same with less code. It relies on short-circuit evaluation of the && operator.
Code: Select all
$uniqueRecords = array_filter($records, function($record){
static $ids = array();
return !isset($ids[$record['id']]) && $ids[$record['id']] = true;
});