Looping through an Array of stdClass Objects, I'd like to add a new property to the Object.
Of all the ways I've tried and researched, none end up adding the new property.
Array
(
[0] => stdClass Object
(
[id] => 12345678
[profile] => stdClass Object
(
[type] => superAdmin
)
)
[1] => stdClass Object
(
[id] => 89101112
[profile] => stdClass Object
(
[type] => admin
)
)
)
I have a function that takes in the above array, and then should iterate through it, if certain criteria met, add a new property to the object, and return the array.
public function addToProfile($usernameArr) {
$users = $usernameArr;
foreach ($users as $key => $user) {
if (in_array("admin", $user->profile->type)) {
$users[$key]->profile->newProperty = "newItem";
}
}
return $users;
}
I've also tried the json_decode(json_encode($users), true) way which did not end up with the result I'm looking for.
You can do it via transformation $user object to the array and back to object:
foreach ($users as $key=>&$user) {
if (in_array("admin", $user->profile->type)) {
// represents current $user->profile object as an array
$tmp = json_decode(json_encode($user->profile),true);
// add a new index
$tmp['newproperty'] = "$key newItem";
// transform back to an object
$user->profile = (object)($tmp);
}
}
Demo
You can put it into the function like:
function addNewProp($data, $prop_name, $prop_val){
foreach ($data as $key=>$user) {
if (in_array("admin", $user->profile->type)) {
$tmp = json_decode(json_encode($user->profile),true);
$tmp[$prop_name] = $prop_val;
$user->profile = (object)($tmp);
}
}
return $data;
}
Demo
Your input value of type has string datatype. Instead of
if (in_array("admin", $user->profile->type)) {
you should use
if ($user->profile->type === "admin") {
Generally, I try and avoid doing things like (object)array(...) and json_decode(json_encode()) in PHP as it is not immediately clear to the reader why your doing this round about stuff, so I will provide an alternative answer.
function addNewProp(array $users, $propName, $propVal)
{
for ($i = 0; $i < count($users); $i++) {
// You may need to do extra checking here if profile and type are not required.
if (isset($users[$i]->profile->type->admin)) {
$users[$i]->profile->$propName = $propVal;
}
}
return $users;
}
Related
I have an objects array like this:
Array
(
[945] => member Object
(
[id] => 13317
[name] => Test 999
[last_name] => Test 999
)
[54] => member Object
(
[id] => 13316
[name] => Manuel
[last_name] => Maria parra
)
[654] => member Object
(
[id] => 13315
[name] => Byron
[last_name] => Castillo
)
[656] => member Object
(
[id] => 13314
[name] => Cesar
[last_name] => Vasquez
)
)
I need to remove one of these objects according to an attribute value.
For example, I want to remove from the array the object id 13316.
Here is the functional approach:
$neededObjects = array_filter(
$objects,
function ($e) use ($idToFilter) {
return $e->id != $idToFilter;
}
);
function filter_by_key($array, $member, $value) {
$filtered = array();
foreach($array as $k => $v) {
if($v->$member != $value)
$filtered[$k] = $v;
}
return $filtered;
}
$array = ...
$array = filter_by_key($array, 'id', 13316);
Use array search function :
//return array index of searched item
$key = array_search($search_value, array_column($list, 'column_name'));
$list[key]; //return array item
Since there is already plenty solutions given, I suggest an alternative to using the array:
$storage = new SplObjectStorage; // create an Object Collection
$storage->attach($memberObject); // add an object to it
$storage->detach($memberObject); // remove that object
You could make this into a custom MemberCollection class with Finder methods and other utility operations, e.g.
class MemberCollection implements IteratorAggregate
{
protected $_storage;
public function __construct()
{
$this->_storage = new SplObjectStorage;
}
public function getIterator()
{
return $this->_storage;
}
public function addMember(IMember $member)
{
$this->_storage->attach($member);
}
public function removeMember(IMember $member)
{
$this->_storage->detach($member);
}
public function removeBy($property, $value)
{
foreach ($this->_storage as $member) {
if($member->$property === $value) {
$this->_storage->detach($member);
}
}
}
}
Might be overkill for your scenario though.
foreach ($array as $key=>$value)
if ($value->id==13316) {
unset($array[$key]);
break;
}
Hi I have an object array ($perms_found) as follow:
Array
(
[0] => stdClass Object
(
[permissions_id] => 1
)
[1] => stdClass Object
(
[permissions_id] => 2
)
[2] => stdClass Object
(
[permissions_id] => 3
)
)
I want to use in_array to find any of the permissions_id , I have tried this:
var_dump(in_array(1, $perms_found , true));
But I keep getting :
bool(false)
What I am doing wrong please help?
in_array is looking for 1 in the array, but your array contains objects, not numbers. Use a loop that accesses the object properties:
$found = false;
foreach ($perms_found as $perm) {
if ($perm->permissions_id == 1) {
$found = true;
break;
}
}
Firstly convert to array...
function objectToArray($object) {
if (!is_object($object) && !is_array($object)) {
return $object;
}
if (is_object($object)) {
$object = get_object_vars($object);
}
return array_map('objectToArray', $object);
}
in_array() will check if the element, in this case 1, exists in the given array.
Aparently you have an array like this:
$perms_found = array(
(object)array('permissions_id' => 1),
(object)array('permissions_id' => 2),
(object)array('permissions_id' => 3)
);
So you have an array with 3 elements, none of them is the numeric 1, they are all objects. You cannot use in_array() in this situation.
If you want to check for the permission_id on those objects, you will have to wrote your own routine.
function is_permission_id_in_set($perm_set, $perm_id)
{
foreach ($perm_set as $perm_obj)
if ($perm_obj->permission_id == $perm_id)
return true;
return false;
}
var_dump(is_permission_id_in_set($perms_found, 1));
Your array is collection of objects and you're checking if an integer is in that array. You should first use array_map function.
$mapped_array = array_map($perms_found, function($item) { return $item->permissions_id });
if (in_array($perm_to_find, $mapped_array)) {
// do something
}
Following is the array with stdClass Object
Array
(
[0] => stdClass Object
(
[Number] => 5
[Content] => 00666
)
[1] => stdClass Object
(
[Number] => 7
[Content] => 1018456550591052212900797790669502
)
)
What I want to get value of Content corresponding to Number
eg. For Number 5 get value 00666
Thank in advance.
add this function:
function returnContent($myObjectArray, $number)
{
foreach($myObjectArray as $obj){
if ($obj->Number == $number)
return $obj->Content;
}
}
return "number not in array"; //or some other value to denote an error
}
call the function something like this:
echo returnContent($objArray, 5);
or assign it to a variable:
$content = returnContent($objArray, 5);
just be sure to check if the number existed:
if ($content != "number not in array"){ //or whatever value you assigned to denote a failure
//do something
}
You can make a function for this:
function getContent($needle, $haystack) {
foreach($haystack as $v) if($needle==$v->Number) return $v->Content;
return null;
}
To use it use:
$result = getContent(5, $myArray);
if($result===null) die('Value not found.');
// Use result however you want now
$myObjectArray= myObjectArray() // array of objects
foreach($myObjectArray as $val) {
echo $val->Content;
}
It will print `00666` and `1018456550591052212900797790669502`
I have an objects array like this:
Array
(
[945] => member Object
(
[id] => 13317
[name] => Test 999
[last_name] => Test 999
)
[54] => member Object
(
[id] => 13316
[name] => Manuel
[last_name] => Maria parra
)
[654] => member Object
(
[id] => 13315
[name] => Byron
[last_name] => Castillo
)
[656] => member Object
(
[id] => 13314
[name] => Cesar
[last_name] => Vasquez
)
)
I need to remove one of these objects according to an attribute value.
For example, I want to remove from the array the object id 13316.
Here is the functional approach:
$neededObjects = array_filter(
$objects,
function ($e) use ($idToFilter) {
return $e->id != $idToFilter;
}
);
function filter_by_key($array, $member, $value) {
$filtered = array();
foreach($array as $k => $v) {
if($v->$member != $value)
$filtered[$k] = $v;
}
return $filtered;
}
$array = ...
$array = filter_by_key($array, 'id', 13316);
Use array search function :
//return array index of searched item
$key = array_search($search_value, array_column($list, 'column_name'));
$list[key]; //return array item
Since there is already plenty solutions given, I suggest an alternative to using the array:
$storage = new SplObjectStorage; // create an Object Collection
$storage->attach($memberObject); // add an object to it
$storage->detach($memberObject); // remove that object
You could make this into a custom MemberCollection class with Finder methods and other utility operations, e.g.
class MemberCollection implements IteratorAggregate
{
protected $_storage;
public function __construct()
{
$this->_storage = new SplObjectStorage;
}
public function getIterator()
{
return $this->_storage;
}
public function addMember(IMember $member)
{
$this->_storage->attach($member);
}
public function removeMember(IMember $member)
{
$this->_storage->detach($member);
}
public function removeBy($property, $value)
{
foreach ($this->_storage as $member) {
if($member->$property === $value) {
$this->_storage->detach($member);
}
}
}
}
Might be overkill for your scenario though.
foreach ($array as $key=>$value)
if ($value->id==13316) {
unset($array[$key]);
break;
}
I have a recursion function that parses an object/array with a global variable. If I comment out the global variable I get nothing but if I leave it in it keeps adding to the array other values that should be in it own result set. Do I need to change something here?
UPDATE #2:
How can I get the return I want, I thought I was pushing all unique values to the array?
function getResp($objectPassed) {
foreach($objectPassed as $element) {
if(is_object($element)) {
// recursive call
$in_arr = getResp($element);
}elseif(is_array($element)) {
$in_arr = getResp($element);
} else {
// XML is being passed, need to strip it
$element = strip_tags($element);
// Trim whitespace
$element = trim($element);
// Push to array
if($element != '') {
if (!preg_match("/^[0-9]$/", $element)) {
if (!in_array($element,$in_arr)) {
$in_arr[] = $element;
}
}
}
}
}
return $in_arr;
}
INPUT:
stdClass Object
(
[done] => 1
[queryLocator] =>
[records] => Array
(
[0] => stdClass Object
(
[type] => typeName
[Id] => Array
(
[0] => a0E50000002jxhmEAA
[1] => a0E50000002jxhmEAA
)
)
[1] => stdClass Object
(
[type] => typeName
[Id] => Array
(
[0] => a0E50000002jxYkEAI
[1] => a0E50000002jxYkEAI
)
)
)
[size] => 2
)
RETURN:
Array
(
[0] => a0E50000002jxYkEAI
)
WANTED RETURN:
Array
(
[0] => a0E50000002jxYkEAI
[1] => a0E50000002jxhmEAA
)
Is a global variable necessary? Otherwise you could simplify it this way:
function getResp($objectPassed, &$in_arr = array()) { // <-- note the reference '&'
foreach($objectPassed as $element) {
if(is_object($element) || is_array($element)) { // <-- else if statement simplified
getResp($element,$in_arr);
} else {
// XML is being passed, need to strip it
$element = strip_tags($element);
// Trim whitespace
$element = trim($element);
// Push to array
if($element != '' && // <-- everything in one test
!preg_match("/^[0-9]$/", $element) &&
!in_array($element,$in_arr))
{
$in_arr[] = $element;
}
}
}
return $in_arr;
}
Then you do:
$result = getResp($data);
If a recursive function has to access the same resource over and over again (in this case the initial array), I would always pass this as a reference.
I don't know if is measurable but I would guess that this is much more efficient than copying values.