2

I have the following example data in PHP:

[{"id": 2088996538},{},{"id": 2077495673}]

How can I end up with

[{"id": 2088996538},{"id": 2077495673}]

I've tried several things, like

unset($activities[1]);

but then I end up with

{"0":{"id":2088996538},"2":{"id":2077495673}}

It looks like something soo simple, but can't figuring it out.

The ultimate goal is to clean up some strava api output, deleting everything I don't use.

Edit:

$activities = json_decode('[{"id": 2088996538},{},{"id": 2077495673}]');
unset($activities[1]);
$activities = array_values($activities);
echo json_encode($activities);

this actually works, how could I've missed it. Gonna try it out with the larger data set. Thanks!

15
  • "I've tried several things" - Show us your attempt and we can help you from there. Commented Jan 24, 2019 at 21:10
  • you're right: I was just editing my attempts :) Commented Jan 24, 2019 at 21:11
  • 2
    JS / JSON doesn't have non-sequential arrays, so they have to export to an object. So the "solution" when using unset is to reset the keys to be sequential (from 0), using e.g. array_values. Commented Jan 24, 2019 at 21:13
  • 2
    Well, if OP wants a JSON array, rather than an object, then... Commented Jan 24, 2019 at 21:19
  • 1
    I would recommend that you check out the answers you got below since they are scaleable compared to manually unsetting the array items. Commented Jan 24, 2019 at 21:19

2 Answers 2

6

You can filter out the empty objects.

$data = array_values(array_filter($data, function($item) {
    return (bool) (array) $item;
}));

array_values is necessary to prevent the {"0":{"id":2088996538},"2":{"id":2077495673}} form you were getting, because it reindexes the array.

The intermediate cast to array in the callback is necessary because any object evaluates to true whether it's empty or not, but an empty array will evaluate to false. If you decode to arrays instead of objects by setting the second parameter of json_decode to true, that cast isn't necessary.


Not directly related to the original question, but here's my suggestion for another way to do this starting with the data from the API:

$activities = json_decode($json, true);

$set_keys = array_flip(["start_latlng", "id", "start_date","name"]);

foreach ($activities as $activity) {
    if (!is_null($activity['start_latlng'])) {
        $result[] = array_intersect_key($activity, $set_keys);
    }
}

echo json_encode($result);
Sign up to request clarification or add additional context in comments.

1 Comment

Wow awesome, only few lines of code and works like a charm! thanks!
3

If you decode to arrays using the second argument, then filtering is easier:

$activities = json_decode('[{"id": 2088996538},{},{"id": 2077495673}]', true);
$activities = array_values(array_filter($activities));

But you still need to re-index if you want sequential indexes.

1 Comment

hope he doesn't need some {foo:false} or {foo:0} or {foo:''} value, but yeah

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.