Blagoh
Blagoh

Reputation: 1235

JSON is object instead of array, if array_diff returns assoc array on Collection->toArray()

My issue is in my json I am expecting an array, but am getting an object.

Details:

I have an array of numbers:

$numbers = [1];

I select from relationship, the "drawn numbers":

    $drawnNumbers = Ball::whereIn('number', $numbers)->where('game_id', $card->game->id)->get()->map(function($ball) {
        return $ball->number;
    })->toArray();

I do a ->toArray() here. I want to find the numbers in $numbers that do not occur in $drawnNumbers. I do so like this:

$numbersNotYetDrawn = array_diff($numbers, $drawnNumbers);

My method then return $numbersNotYetDrawn (my headers accept is application/json).

So now the issue. When $drawnNumbers is an empty array, then the printed json is a regular array like this:

[
    1
]

However if the relationship returns $drawnNumbers to be an array with numbers, then json is printed as an object:

{
    "0" => 1
}

Does anyone know why this is? Anyway to ensure that json is array?

Edit:

Here is my actual data:

$drawnNumbers = Ball::whereIn('number', $numbers)->where('game_id', $card->game->id)->get()->map(function($ball) {
            return $ball->number;
        })->toArray();

$undrawnNumbers = array_diff($numbers, $drawnNumbers);
// $undrawnNumbers = array_values(array_diff($numbers, $drawnNumbers)); // temp fix

Upvotes: 2

Views: 994

Answers (2)

Ibrahim Chawa
Ibrahim Chawa

Reputation: 981

I recently had this same problem and wondered the same thing. I solved it by adding "array_values", but I was wondering how to reproduce it. I found it that it is reproduced when array_diff removes an element from the array that isn't the last element. So:

>>> $x
=> [
     1,
     2,
     3,
     4,
     5,
   ]
>>> array_diff($x, [5]);
=> [
     1,
     2,
     3,
     4,
   ]
>>> array_diff($x, [1]);
=> [
     1 => 2,
     2 => 3,
     3 => 4,
     4 => 5,
   ]

Upvotes: 0

jedrzej.kurylo
jedrzej.kurylo

Reputation: 40909

Replace

$numbersNotYetDrawn = array_diff($numbers, $drawnNumbers);

with

$numbersNotYetDrawn = array_values(array_diff($numbers, $drawnNumbers));

to make sure element keys are reset and array is treated as a simple list and serialized to a JSON list - instead of being treated as an associative array and serialized to a JSON object.

Upvotes: 4

Related Questions