7

I have an indexed array that holds a few associative arrays and I apply a simple

$my_arr = array_filter($my_arr, function($obj) {
    return $obj["value"] < 100;
});

function to filter some of the items in the array.

This started to make my Angular front end bug in weird ways, so after a few minutes I discovered that $my_arr was being converted from an indexed array to an associative array.

  • Is this the expected behavior in array_filter?
  • How can I tell array_filter that I want an indexed array?

EDIT: As requested in the comments, my $my_arr:

$my_arr = [
    ["foo" => "bar", "value" => 10],
    ["foo" => "var", "value" => 30],
    ["foo" => "car", "value" => 440],
    ["foo" => "dar", "value" => 700]
]

EDIT: Real-world extract from my code:

$media = [
    "photos" => [
        ["foo" => "bar", "value" => 10],
        ["foo" => "var", "value" => 20],
        ["foo" => "car", "value" => 50],
    ]
];

echo json_encode($media);
echo "\n\n";

$media["photos"] = array_filter($media["photos"], function($photo) {
    return $photo["value"] > 15;
});

echo json_encode($media); 

Output:

{"photos":[{"foo":"bar","value":10},{"foo":"var","value":20},{"foo":"car","value":50}]}

{"photos":{"1":{"foo":"var","value":20},"2":{"foo":"car","value":50}}}

Expected output:

{"photos":[{"foo":"bar","value":10},{"foo":"var","value":20},{"foo":"car","value":50}]}

{"photos":[{"foo":"var","value":20},{"foo":"car","value":50}]}
dreftymac
  • 31,404
  • 26
  • 119
  • 182
alexandernst
  • 14,352
  • 22
  • 97
  • 197

1 Answers1

12

The array is not being converted from one type to the other - they're the same thing in PHP. It's just that array_filter() is preserving the key/value associations when filtering. There is no way to automatically reindex the array according to the documentation, so you have to do it manually:

$my_arr = array_values(array_filter($my_arr, function($obj) {
    return $obj["value"] < 100;
}));
Anonymous
  • 11,740
  • 3
  • 40
  • 50
  • While this works, it feels extremely durty (and rubbish, not because of the solution, but because of how PHP is threating my data). Is this really how (badly) PHP handles arrays vs objects? – alexandernst Jul 25 '15 at 11:20
  • 2
    @alexandernst The thing is, that array_filter, just filters values out, so the remaining elements keep their keys and don't get reindex. And if you `json_encode()` an array, which is not 0 based indexed, then it will add the keys in the output. So in your example key 0 is missing and it gets interpreted as associative array. That's why you have to reindex your keys with `array_values()`, so that `json_enocde()` see's the 0 based indexed array and doesn't include the keys in the output. – Rizier123 Jul 25 '15 at 11:24
  • @Rizier123 Ok, one last question. Do you know if some future version of PHP (7 maybe?) will allow me to actually declare associative/indexed arrays with each owns syntax? Something like `$a = []; (indexed array)` and `$b = {}; (associative array)` – alexandernst Jul 25 '15 at 11:26
  • @alexandernst no, why should they do that? Just as always: `$array = ["normalKey" => "value"];` – Rizier123 Jul 25 '15 at 11:28
  • @Rizier123 Because an array and an object (what php calls associative array) are to completely different things and we wouldn't need to do those hacks/solutions if we could actually declare our variables with the "right" data type. – alexandernst Jul 25 '15 at 11:31
  • @alexandernst No, now you are mixing stuff! array !== object. An object is not an associative array! – Rizier123 Jul 25 '15 at 11:32
  • @Rizier123 When I said "object" I was talking about the "object" type of data in Javascript – alexandernst Jul 25 '15 at 11:36
  • @alexandernst, php is not a statically typed language. Also, technically all php arrays are associative arrays. Real arrays in c for example are located in adjacent memory. In, php this isn't the case. Enjoy. – Raphael Rafatpanah Jul 25 '15 at 11:37
  • This is the normal way of solving this problem in PHP. It may be dirty in other languages but not here. PHP7 will not be splitting the array into two types since that would break literally every program in existence - the array (aka sorted map) is the only data structure available. Welcome to PHP. – Anonymous Jul 25 '15 at 11:39
  • This is still valid, i ran into this issue and where filter would return the preserved index assosiative array. – Karim Dec 12 '19 at 13:20