Changing values of an array which consists of multiple objects - php

I would like to replace a value within the path array and I'm quite stuck for a while. So here is what I got.
My array:
// $myArr
Array
(
[0] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Bob
[1] => pictures
[2] => food
)
)
)
[1] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Alice
[1] => pictures
[2] => vacations
[3] => rome
)
)
)
)
PHP code:
for ($i=0; $i < count($myArr) ; $i++) {
$search = array($old_name); // pictures
$replace = array($new_name); // test
$result = str_replace($search, $replace, $myArr[$i]->doc->path);
}
Result:
It only changes one array and gives me a hint on my str_replace line. Both, $search and $replace are of type array and I know that I need to access elements in an array via array notation -> $item['price'] for example. That is not what is wrong here right?
Notice: Trying to get property of non-object in ...
Array
(
[0] => Bob
[1] => test
[2] => food
)
1) Do you see why he only modifies the last object so to speak?
2) Why is he giving me a Notice whereas I don't violate type conventions in my opinion?

Your code is working fine on my end, however..
I think the problem is in your $result variable. With every iteration, you are overwriting the last written value in the array.
You have to either use that $result variable directly, or replace $result by $myArr[$i]->doc->path. That way you can use the $myArr with the rewritten values.

Related

Problems changing values in an array/object nested combination array

I don't know what to do to get this done what would like to do. I tried multiple approaches, e.g. I used array_map, array_walk, nested foreach loops with get_object_vars and I worked with json_decode/encode and so on. I always come a little bit further but never reach my goal and I would like to get some guidance from you
Basically when you see the array below, how would you proceed when you want to change some value in the path array for multiple values in the array itself?
My questions:
1) Is it right that I must convert both nested objects to an array first or is this not nesessary to do this? I mean I always get some type conversion error which tells me that I either have everything as an object or array. Is this right?
2) If this mistery is solved, which php array function is the appropriate one to change values in an array(/object)? As I have written above, I tried so many and I don't see the trees in the woods anymore. Which one do you suggest to me to use in a foreach loop?
Array
(
[0] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Bob
[1] => pictures
[2] => food
)
)
)
[1] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Alice
[1] => pictures
[2] => vacations
[3] => rome
)
)
)
)
I would suggest that,
you create an array with keys as new path and value as old path (
path to be replaced).
Loop you path array and check if it is available in above defined array.
If available replace it with key of above defined array.
For example
// array defined as point 1
$change_path_array= array('pics'=>'pictures','meal'=>'food');
// $array is your array.
foreach ($array as $value) {
// loop you path array
for($i=0;$i<count($value->doc->path);$i++){
// check if the value is in defined array
if(in_array($value->doc->path[$i],$change_path_array)){
// get the key and replace it.
$value->doc->path[$i] = array_search($value->doc->path[$i], $change_path_array);
}
}
}
Out Put: picture is replaced with pics and food with meal
Array
(
[0] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Bob
[1] => pics
[2] => meal
)
)
)
[1] => stdClass Object
(
[doc] => stdClass Object
(
[path] => Array
(
[0] => Alice
[1] => pics
[2] => vacations
[3] => rome
)
)
)
)
You can modify the code to check casesensitive.
Example of changing all pictures to photos:
$doc1 = new \stdClass;
$doc1->doc = new \stdClass;
$doc1->doc->path = array('Bob', 'pictures', 'food');
$doc2 = new \stdClass;
$doc2->doc = new \stdClass;
$doc2->doc->path = array('Alice', 'pictures', 'vacations', 'rome');
$documents = array($doc1, $doc2);
/* change all 'pictures' to 'photos' */
foreach ($documents as &$doc) {
foreach ($doc->doc->path as &$element) {
if ($element == 'pictures') {
$element = 'photos';
}
unset($element);
}
unset($doc);
}
print_r($documents);
You can do it like this:
for($i = 0; $i < count($arr); $i++){
$path_array = $arr[$i]->doc->path;
// do your modifications for [i]th path element
// in your case replace all 'Bob's with 'Joe's
$path_array = array_map(function($paths){
if($paths == 'Bob') return 'Joe';
return $paths;
}, $paths_array);
$arr[$i]->doc->path = $path_array;
}

PHP: How to extract a property from this array

I have an array of values returned from Facebook - let's call it $array.
If I do print_r($array) - it looks like this:
Array
(
[code] => 200
[headers] => Array
(
[0] => Array
(
[name] => Some value
[value] => *
)
[1] => Array
(
[name] => Some value
[value] => Some value
)
[2] => Array
(
[name] => Some value
[value] => Some value
)
)
[body] => {"about":"Some more values.","can_post":true}
)
I need to extract the body part from this array.
I cannot refer to it by it's position, I'm looking for something like $array->body and receive the {....} string.
$array->body would work if the variable $array was an object
For arrays, just use:
$body = $array['body'];
(see: http://be2.php.net/manual/en/language.types.array.php)
If you want to access to your array via -> just do 1 more step:
$array = (object) $array;
And now, you can access to your body via:
$array->body;
Else without this step there is just one way:
$array['body'];
If you are more interested about converting arrays into objects, you can visit this question: How to convert an array to object in PHP?
Access array elements by using their name.
$array['body'];

PDO fetchAll() primary key as array group key

I want to store the contents of a specific database into an array, grouped by their primary keys. (Instead of the useless way PDO fetchAll() organises them).
My current code:
$DownloadsPDO = $database->dbh->prepare("SELECT * FROM `downloads`");
$DownloadsArray = $DownloadsPDO->execute();
$DownloadsArray = $DownloadsPDO->fetchAll();
Which then outputs:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
I was considering to use PDO::FETCH_PAIR, however I will be very soon expanding the amount of data I want to be able to use on this script. This works currently, but when I start to expand the amount of downloads and more clients come into play, obviously the way the data is grouped causes an issue.
Is it possible for me to group each array by their primary key (which is id)?
You can just use
$results = array_map('reset', $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC))
PDO::FETCH_GROUP|PDO::FETCH_ASSOC returns an array of arrays. The first column is used as the key, and then within key is an array of all the results for that key. However, in our scenario each key will only contain 1 row. reset() returns the first element in array, thus eliminating 1 level of nesting.
This should yield what you are looking for :
$results = $pdos->fetchAll(\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
I decided to just loop through the results with fetch() and enter them into an array as I go along, this is the code I have used and it works just fine:
$DownloadsPDO = $database->dbh->query("SELECT * FROM `downloads`");
$Array = array();
while ($d = $DownloadsPDO->fetch()) {
$Array[$d['id']]["id"] = $d['id'];
$Array[$d['id']]["name"] = $d['name'];
$Array[$d['id']]["path"] = $d['path'];
}
// Outputs
Array ( [1] => Array ( [id] => 1 [name] => Test Script [path] => /xxxx/testfile.zip ) [2] => Array ( [id] => 2 [name] => New Script-UPDATE [path] => /xxxx/testfile.zip ) )
Which uses the primary key (being id) as the name for the array key, and then adds the data into it.
Thought I would add this as the answer as this solved it, thanks to the guys that helped out and I hope this is helpful to anyone else hoping to achieve the same thing.
I'd like to point out the only solution that works for me:
fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
Beware that this will strip the first column from the resultset. So the query must be:
SELECT id_keyname AS arrkey, id_keyname, .... FROM ...
I'm still suggesting you to loop using fetch() method. Otherwise, you can use array_reduce() to iterate over the array. A sample on codepad is here.
The code(in human readable form) will be:
$myFinalArray = array_reduce($myInputArray, function($returnArray, $temp) {
$temp2 = $temp['id'];
unset($temp['id']);
$returnArray[$temp2] = $temp;
return $returnArray;
}
);
So, my question is; is it possible for me to group each array by their
primary key (which is id)
Off course, you have 2 options here: Either to change the query or parse a result-set.
So, I'm sure you don't want to change query itself, so I'd go with parsing result-set.
Note:
You should use prepared SQL statements when they make sense. If you want to bind some parameters then its OKAY. But in this case, you only want get get result-set, so prepare() and fetch() will be kinda overdo.
So, you have:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
And you want:
Array( [id] => Array('bar' => 'foo') ....)
Well, you can do something like this:
$stmt = $database->dbh->query("SELECT * FROM `downloads`");
$result = array();
foreach($stmt as $array){
$result[$array['id']] = $array;
}
print_r($result); // Outputs: Array(Array('id' => Array(...)))

Multi dimensional array, with an object for good measure - iteration?

This one is starting to get on my nerves. Still fairly new to arrays and objects.
I need to be able to pull out [id] in the numbered array, plus get access to the lonely snippet_count at the end.
I can do it if there is no top level container array using a foreach $a as $k => $v., (from an earlier SO question) but am struggling a level deeper. Thanks.
Array
(
[snippets] => Array
(
[0] => stdClass Object
(
[id] => 123456789
)
[1] => stdClass Object
(
[id] => 123456789
)
[2] => stdClass Object
(
[id] => 123456789
)
//and so on
)
[snippet_count] => 500
)
You can iterate over just the snippets array to get the IDs
$ids = array();
foreach ($array['snippets'] as $snippet) {
$ids[] = $snippet->id;
}
$count = $array['snippet_count'];
Is this what you're looking for?

How to access stdclass object after a specific key value pair?

I have a stdclass object as shown below:
stdClass Object
(
[text] => Parent
[values] => Array
(
[0] => stdClass Object
(
[id] => /m/0c02911
[text] => Laurence W. Lane Jr.
[url] => http://www.freebase.com/view/m/0c02911
)
)
)
I iterate over multiple such objects, some of which have
stdClass Object
(
[text] => Named after
[values] => Array
(
[0] => stdClass Object
(
[id] => /m/0c02911
[text] => Stanford
[url] => SomeURL
)
)
)
I was wondering how I would access the "values" object if it comes after a "text" that has "Parent" as its value?
there are serveral ways to turn it to array:
First Solution:
$value = get_object_vars($object);
Second Solution:
$value = (array) $object;
Third Solution
$value = json_decode(json_encode($object), true);
to get value of converted array
echo $value['values']['0']['id'];
The alternate way to access objects var without convert the object, try
$object->values->{'0'}->id
Expanding (or rather minimalizing) upon answer by Somwang Souksavatd, I like accessing Object values like this:
echo get_object_vars($object)['values']['0']['id'];
I had the same issue, still not so sure why but I was able to get it working using this workaround:
$k2 ="1";
$elements = json_decode('{"id":"1","name":"User1"}');
//$elements['id'] == $k2; //****Not Working
$tmp = (object)$elements;
$tmp = $tmp ->id; //****Working
//$tmp =$elements['id'] ; //****Not Working
return $tmp == $k2;
I have to say that sometimes accessing the element as array works and some times not,(On PHP7 it worked for me but on PHP5.6 it didn't).
$elements can be Array to but I chose to demonstrate with json string.
I hope this helps somehow !!!
$Obj=stdClass Object
(
[text] => Named after
[values] => Array
(
[0] => stdClass Object
(
[id] => /m/0c02911
[text] => Stanford
[url] => SomeURL
)
)
)
$Values= $result->values;
$Item = $Values[0];
$id=$Item->id;
$text = $Item->text;
$url=$Item->url;
I'm doing the same thing and all I did was this;
<?php
$stdObject = json_decode($stdClassObject);
print $stdObject->values[0]->id;
this can help you accessing subarrays in php using codeigniter framework
foreach ($cassule['tarefa'][0] as $tarefa => $novo_puto_ultimos_30_dias) {
echo $novo_puto_ultimos_30_dias;
What you are looking for is the Object['values'][0]: 'values' is the keymap just like 'text', and [0] is the index inside that array you wish to access. so if you would like to get the id deep in the nest, you'd have to do something like
Object['values'][0]['id']
or
Object['values'][0]->id
which should give you /m/0c02911. But I have no idea how you are doing your loop, so you will have to adjust it to your needs and place proper variables where they need to go in that code in your loop. Not exactly sure which language you are working with.

Categories