Extract elements from stdClass in PHP dynamically - php

I have stdClass returned from Laravel ORM result which looks like below,
I know I can access the value using $object->Tables_in_questip3_qgen, but "Tables_in_questip3_qgen" is dynamic. This can change to any string and I would like to extract values only from first element. I would like to have only adj_table,admin_fi and admin_fi_acount values across rows.

In Laravel 5+ you can do this:
collect($object)->map(function ($v) {
return head((array)$v);
});
To get a subarray of arbitrary items (by the order they appear):
$indices = [ 0, 1 ];
collect($object)->map(function ($v) use ($indices) {
$inner = collect($v)->values();
return $inner->only($indices); //This will return the requested indices as a collection, but you can realistically do whatever you want with them like e.g. ->implode or ->toArray
});

Related

Extract particular array from multidimensional array

I have a JSON array of data that I am trying to extract particular value/keys(?) from, and would like to add them into a new array.
The array looks like this:
{ "total':2000,
"achievements":[
{
"id":6,
"achievement":{},
"criteria":{
"id":2050,
"is_completed":false
},
"completed_timestamp":1224053510000
},
{
"id":8,
"achievement":{},
"criteria":{
"id":1289,
"is_completed":true
},
"completed_timestamp":0000000
}
]
}
I want to search for true in the is_completed, and then add the id from that array into a new array.
Basically, find the id's of all the key/array (sorry unsure of terminology) where is_completed is true.
I've tried something simple like finding trying to find the key of an ID, but struggling to get that to work. And also seen some of the multi-level for loop examples but can't get them to work for my data.
Example:
$key = array_search('1289', array_column($array, 'id'));
As pointed out in the comments, you could combine array_filter (to filter completed events) and array_column (to extract their IDs).
$completedAchievements = array_filter(
$array->achievements,
static function (\stdClass $achievement): bool {
return $achievement->criteria->is_completed === true;
}
);
$completedAchievementsIds = array_column($completedAchievements, 'id');
print_r($completedAchievementsIds); // Array([0] => 8)
Note: the code above supposes your JSON was decoded as an object. If it was decoded as an array, just replace -> syntax with the corresponding array index access.
Demo

Array_map through a array of objects and grab properties

So I have a var_dump($instagram->get_images()); that gives me the following output:
I want to use array_map to map through all the properties and use them inside a foreach loop later on.. but I'm running into some issues:
Here is the attempt that I have:
$mediaUrls = array_map(function($entry) {
return [
'media_url' => $entry['media_url'],
];
}, $instagram->get_images());
I'm getting back the following error:
Could someone assist me on properly array_mapping through the objects and then later be able to use foreach ($MediaUrls as $media) etc...
The error is correct. You're using array map on an object. But the object does have a ->data property that is an array. But the items in the array are objects, so you'll need to refer to their properties rather than using array syntax.
$images = $instagram->get_images();
$mediaUrls = array_map(function($entry) {
return [
'media_url' => $entry->media_url,
];
}, $images->data);
Couple of suggestions. You said, "I want to use array_map to map through all the properties and use them inside a foreach loop later on."
You can reiterate $images->data later on, so I don't really see the value of making another array just for that purpose
foreach ($images->data as $imageData) {
// do something with $imageData->media_url
}
This would be almost exactly the same as iterating the array you're making with array_map.
foreach ($images->data as $imageData) {
// do something with $imageData['media_url']
}
If you want to get an array of just the urls, you can do it more simply with array_column.
$images = $instagram->get_images();
$mediaUrls = array_column($images->data, 'media_url');
(This won't give you the same result. It will be an array of strings rather than an array of arrays.)

laravel - trying to remove item from fetched collection

I need to remove items from a collection based on an attribute (Laravel 5.6).
$leagues = League::all();
foreach($leagues as $i => $L){
if($L->status == LeagueStatus::HIDDEN){
$leagues->forget($i); <<<<======== 1st attempt
unset($leagues[$i]); <<<<======== 2nd attempt
}
}
return response()->json($leagues->toArray());
Both methods removes the items correctly, but causes that response JSON comes as object:
{ <<<<======== ITS OBJECT WITH NUMBERED KEYS, NOT ARRAY
"0":{
"id":1,
"title":"test...
Correct JSON would be:
[ <<<<======== NORMAL ARRAY WITH OBJECTS
{
"id":1,
"title":"test...
Am I doing something wrong?
Use values to get a new Collection with the keys reset to consecutive integers:
return response()->json($leagues->values());
Laravel 6.x Docs - Collections - Available Methods - values
Just replace this
return response()->json($leagues->toArray());
to
return json_decode($leagues);

PHP sort objects value but retain original relative order [duplicate]

This question already has answers here:
Preserve key order (stable sort) when sorting with PHP's uasort
(6 answers)
Closed 5 months ago.
I'm using usort to sort an array of objects, but really I want this to act as a kind of "group by" function without disturbing the original relative order of the rows.
Say I have this:
MASTER_CODE, CONFIG_ITEM
foo1, opt_ray
foo2, opt_ray
foo1, opt_fah
foo2, opt_doe
From that data, an array of objects is constructed with an anonymous key. That is, each row is parsed as an object. The objects are collected into an array.
What I want to do is sort the array by the MASTER_CODE value, but without disturbing the order.
That is, the final order should be:
MASTER_CODE, CONFIG_ITEM
foo1, opt_ray
foo1, opt_fah
foo2, opt_ray
foo2, opt_doe
We don't add a sort order, because the data comes from an external source.
I can use usort to order by the master code, but it messes up the original relative order.
Any suggestions?
This is one option - it's not the most elegant solution. It will take the unique values from the first column of your array (the one you want to filter by), sort that, then loop it and add entries from your original array with the same first value.
// Get an unique array of values to use for sorting
$sorting = array_unique(array_column($a, 0));
sort($sorting);
$sorted = [];
foreach ($sorting as $sortValue) {
$sorted = array_merge(
$sorted,
array_filter(
$a,
function($row) use ($sortValue) {
// Find values that have the same first value as each sort value
return ($sortValue === $row[0]);
}
)
);
}
Example
Note: This will work on PHP 5.5. Since you also tagged PHP 5.3, you may need to replace the array_column function. Try something like this:
$sorting = array_unique(array_map(function($row) { return $row[0]; }, $a));

Navigating a returned object

In PHP I have a multidimensional object created from looping through a list of ids
$summary = array();
foreach ( $request->id as $id ) {
...
$summary[] = $summary_data;
}
it's then passed to my javascript.
return json_encode(array('summary' => $summary));
Not sure how to navigate the returned object correctly. Do I have to use the original list of id's, and use that as an index against this object? Or is there a better way to keep track of this?
End result, I want a select box such that when a new item is selected, its data is displayed.
A general JSON object would look like this (trying to put all possible cases):
{
"key1":"value1",
"subObject":{
"subKey1":"subValue1",
"subKey2":"subValue2"
},
"arrayOfSubObjects":[
{"subKey3":"subValue3"},
{"subKey4":"subValue4"}
]
}
You can reference any element of a JSON object with jsonObject.key, but remember those part between [] are arrays so you'll need to index them as if they were in an array so:
// to point subKey1:
jsonObject.subObject.subKey1;
// to point subKey3
jsonObject.arrayOfSubObjects[0].subKey3;
OR
// to point subKey1:
jsonObject["subObject"]["subKey1"];
// to point subKey3
jsonObject["arrayOfSubObjects"][0]["subKey3"];
note the 0 has no quotes because it's an index.

Categories