Foreach duplicating when creating object of objects - php

What I have
So I have a variable named result that is formatted like this:
Array
(
[0] => stdClass Object
(
[description] => dev1
[id] => 09A
[sum] => 52
[completed_pct_completed] => 97.97
[completed_pct_1msec] => 11.44
....
)
[1] => stdClass Object
(
[description] => dev1
[id] => 273
[sum] => 59
[completed_pct_completed] => 94.43
[completed_pct_1msec] => 10.95
....
)
[2] => stdClass Object
(
[description] => dev1.1
[id] => 28A
[sum] => 39
[completed_pct_completed] => 95.55
[completed_pct_1msec] => 20.78
....
)
[3] => stdClass Object
(
[description] => dev1.1
[id] => 28B
[sum] => 31
[completed_pct_completed] => 91.55
[completed_pct_1msec] => 28.78
....
)
....
There are about 250 different objects. The problem with this current order is that the description of each becomes redundant to the point that I just one want to put all the data of each description into an object. Descriptions go by dev1.x, where x can be a different number or letter or whatever, doesn't matter.
What I want to do:
I'm trying to reorder $result into the format below. Pretty much, by traversing each item in the $result array, each description in result will be it's own property in a new object. Inside of each description property will be subitems like id, sum, completed_pct_completed, etc. It will look like this:
stdClass Object
(
[dev1] => stdClass Object
(
[id] => Array
(
[0] => 182
[1] => 218
[2] => 218
[3] => 021
[4] => 186
[5] => 287
[6] => 21A
)
[sum] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_completed] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_1msec] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
.........
)
[dev1.1] => stdClass Object
(
[id] => Array
(
[0] => 182
[1] => 329
[2] => 465
[3] => 685
[4] => 686
[5] => 607
[6] => 61A
)
[sum] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_completed] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
[completed_pct_1msec] => Array
(
[0] => 567
[1] => 567
[2] => 567
[3] => 567
[4] => 567
[5] => 567
[6] => 567
)
............
)
............
What I've done so far
So here's how I've constructed what I want so far:
I made an object with properties of each unique description:
$object = new STDClass();
//$flipped is the transposed version of $result, then I got unique names
foreach (array_unique($flipped['description']) as $string)
$object->{$string} = array();
This went perfectly fine. Then, I added the subitems to each description property in $object
$dummyObject = new STDClass();
foreach ($object as $objectKey=>$objectValue) {
foreach ($result[0] as $key=>$value){
if ($key!='description'){
$dummyObject->{$key}=array();
$object->$objectKey=$dummyObject;
}
}
}
This also went fine.
The problem here is inserting the data into each id and summary, etc.. Here's what I've done:
//add data to the subitems
//foreach dev1.x => array
foreach ($object as $key => $nextObject)
{
//foreach array as subitems(id, board, etc.) => array
foreach ($nextObject as $nextKey => $dataArray)
{
$dummyArray = array();
foreach ($result as $array)
{
foreach ($array as $arrayKey => $arrayValue)
{
if ($array->{'description'} == $key) {
if ($nextKey == $arrayKey) {
$dummyArray[]=$arrayValue;
}
}
}
}
$object->{$key}->{$nextKey} = $dummyArray;
}
}
In the end, all the data from the last dev1.x property ends up being overwritten into every single dev1.x property. I've tried adding break; in multiple places hoping that I'd be able to deduce what is going wrong. I have a gut feeling that there's more going on than I know with the foreach statements. Would anyone mind helping me with this?
Thanks

It looks like it may be less complicated than it seems. Unless I'm misunderstanding what the transformation should be, you can do it like this:
foreach ($result as $obj) {
foreach ($obj as $key => $value) {
if ($key != 'description') {
$new_result->{$obj->description}->$key[] = $value;
}
}
}
This should create the object and add the appropriate properties and values all at once.
The reason you're getting the duplication is in this part:
$dummyObject = new STDClass();
foreach ($object as $objectKey=>$objectValue) {
foreach ($result[0] as $key=>$value){
if ($key!='description'){
$dummyObject->{$key}=array();
$object->$objectKey=$dummyObject;
}
}
}
When you do $object->$objectKey=$dummyObject; because you created the object before the loop, you're resetting and reassigning the same object to each $objectKey. So when you fill it with values later, you just end up with multiple copies of whatever the last one was. If you use a copy of the object insteady ($object->$objectKey= clone $dummyObject;) it should work. But it does seem a bit overcomplicated.

Just create keys while iterating:
$data = new stdClass();
foreach ($result as $object) {
$description = $object->description;
isset($data->{$description}) or $data->{$description} = new stdClass();
foreach ($object as $name => $value) {
if ($name === 'description') { continue; }
$data->{$description}->{$name}[] = $value;
}
}
I don't like descriptions as field names though. Access to $data->{'dev1.1'} is ugly. Would pack it into an array of objects, but description property would be just a string and other properties would be aggregated arrays. It would need some changes in procedure (index of descriptions propably).

Related

Get Data from database using array values with for loop in PHP

Array:
$ecodesAr = Array (
[0] => 1Z0-060
[1] => 98-375
[2] => 98-368
[3] => 98-367 )
for($k=0; $k<count($ecodesAr); $k++){
$arrayTB[$k] = $this->Functions->exam('title', $ecodesAr[$k]); }
Modal code:
public function exam($q, $d) {
$q = $this->db->where($q, $d)
->get('exams');
return $q->row();
}
Result:
Array (
[0] =>
[1] =>
[2] =>
[3] => stdClass Object ( [id] => 1091 [hot_exam] => 0 [top_exam] => 0 [category] => 114 [subcats] => 288 [slug] => 98-367 [sku] => OI5Ao [title] => 98-367 [name] => MTA Security Fundamentals [update] => 2021-09-16 [regular_price] => 130 [sale_price] => 59 [on_homepage] => 0 [on_request] => 0 [expired] => 0 [path_slug] => 98-367.pdf [questions] => 123 [demo_slug] => 98-367-demo.pdf [prc_price] => 65 [prc_demo] => 98-367-demo [prc_exam] => 98-367 [is_active] => 1 )
)
The First 3 values are skiped in the output and just the last value got, I want to all array data against values please help anyone!
$productsarry = Array (
[0] => Milk
[1] => Cream
[2] => Sugar
[3] => Yougert
);
for($k = 0; $k < count($productsarry); $k++) {
$arrayTB[$k] = query("select slug, qty, name, price from exams where title ='$ecode'")->row();
}

Access data inside stdObject

I have stdClass data after submitting the form:
"Array
(
[0] => stdClass Object
(
[username] => stdClass Object
(
[0] => 1001037
[1] => AARONJAMES
[2] => 1
[3] => ULTIMA (Red)
[4] => 1001037|1
[staff_id] => 1001037
[username] => AARONJAMES
[fkhouseid] => 1
[hname] => ULTIMA (Red)
[id] => 1001037|1
[$$hashKey] => object:13
)
[$$hashKey] => object:6
[points] => 50
)
[1] => stdClass Object
(
[username] => stdClass Object
(
[0] => 1001075
[1] => AARONKOH
[2] => 2
[3] => NACHOZZ (Purple)
[4] => 1001075|2
[staff_id] => 1001075
[username] => AARONKOH
[fkhouseid] => 2
[hname] => NACHOZZ (Purple)
[id] => 1001075|2
[$$hashKey] => object:14
)
[house] =>
[points] => 20
[$$hashKey] => object:306
)
)"
I want to access id variable inside username array to explode it later and insert data into database.
I tried to use to access it but it didnt work:
foreach ($persons as $key => $object) {
var_dump($persons[$key]->id);
}
How can I access id variable inside username?
Assuming $persons have array. You can try like below.
foreach ($persons as $key => $object) {
var_dump($object->username->id);
}
As per my comments you should try this
foreach ($persons as $key => $object) {
echo $object[$key]->username->id;
}
some details about array
$key is the index number of person array.
username is the stdClass Object so you can get like this ->username.

how to remove element from reference array in php?

I am using before code to get every first id and remove that id but it show error undefine offset.
I don't understand What i missed in the below code ?
$products = Array
(
[32] => Array
(
[0] => 44
[1] => 45
[2] => 926
[3] => 927
[4] => 930
[5] => 931
)
[41] => Array
(
[0] => 928
[1] => 933
[2] => 969
[3] => 970
[4] => 971
[5] => 972
[6] => 973
[7] => 974
[8] => 975
[9] => 976
[10] => 977
[11] => 978
[12] => 979
[13] => 980
[14] => 981));
$in_array = array();
for($i=0;$i<12;)
{
foreach($products as &$brands):
if(isset($brands[0]))
{
$id = $brands[0];// get the first element
unset( $brands[0]); // have remove that element form products
// But here it show error undefine offset 0
array_push($in_array,$id);
/*if(($key1 = array_search($id, $brands)) !== false) {
unset($brands[$key1]);
}*/
//I tried this too same error
$i++;
}
endforeach;
}
$brands[0] doesn't seem to exist(I only see 32 and 41 in your code).
If you'd like to remove the first element in $products[32] than you need another foreach in your foreach:
foreach($products as $brands) {
foreach($brands as $brand) {
//Here is where you can reach $brand[0](Which is 44 in $products[32])
}
}
If you'd like to remove the first element of the array, you can use array_shift
By the help of mr #CaptainCarl i change my loop it working fine
for($i=0;$i<12;)
{
foreach($products_ids as $key=>$brands):
if(isset($brands[0]))
{
$id = $brands[0];
array_push($in_array,$id);
array_shift($brands);
$i++;
}
$products_ids[$key] = $brands;
endforeach;
}

comparing array value from multidimensional array with index

I have a multidimensional array that loks lik this:
Array
(
[0] => Array
(
[name] => >chr1:2198584545754_genome_1000+
[score] => 511
[hit] => 50
)
[1] => Array
(
[name] => >chr2:2198581212154_genome_1000+
[score] => 620
[hit] => 80
)
[2] => Array
(
[name] => >chr3:2115151215754_genome_1000+
[score] => 666
[hit] => 90
)
[3] => Array
(
[name] => >chr4:2198584545754_genome_1000+
[score] => 750
[hit] => 50
)
[4] => Array
(
[name] => >chr5:1218455145754_genome_1000+
[score] => 800
[hit] => 100
)
[5] => Array
(
[name] => >chr6:1231354645454_genome_1000+
[score] => 850
[hit] => 110
)
[6] => Array
(
[name] => >chr7:1231213211134_genome_1000+
[score] => 900
[hit] => 120
)
)
I have a foreach loop which will loop through each letter of a random sequence and use the index to give each letter a number value.
If the value of ['hit'] matches the index value of the random sequence
i want to insert a function.
I cannot figure this out. I think my problem is in callng each value of ['hit'] and comparing with index. Does anyone know how to do this ?
thanks
To put DaveRandom's comment into an answer (with minor amends):
foreach ($outerArray as $index => $innerArray)
{
if($innerArray['hit'] === $index)
{
doSomething();
}
}
#DaveRandom - feel free to delete or re-post this as your own answer if I'm posting out of turn here...
foreach ($array as $key) {
if ($key['hit'] == $index)
{
// you function or logic here
}
}

Remove duplicates from multi-dimensional array based on higher points

I'm racking my brains trying to think of a solution. I can find plenty of solutions to remove dupes from a 2d array but I need to remove dupes where a value is lower than the other. Here is the array:
Array
(
[basketball] => Array
(
[0] => stdClass Object
(
[id] => 2
[username] => Beans
[points] => 30
)
[1] => stdClass Object
(
[id] => 314
[username] => slights
[points] => 20
)
[2] => stdClass Object
(
[id] => 123
[username] => gibb54
[points] => 5
)
)
[soccer] => Array
(
[0] => stdClass Object
(
[id] => 2
[username] => Beans
[points] => 95
)
[1] => stdClass Object
(
[id] => 49
[username] => sans
[points] => 65
)
[2] => stdClass Object
(
[id] => 122
[username] => peano
[points] => 50
)
[3] => stdClass Object
(
[id] => 174
[username] => fordb
[points] => 30
)
[4] => stdClass Object
(
[id] => 112
[username] => danc
[points] => 30
)
)
)
As you may see, user ID 2, Beans is the first selection for both basketball and soccer. As they have more points for soccer, I need to remove their entry for basketball to make ID 314, slights the 0 value.
I would need to do this continually until no user be the 0 value for any of the primary array values twice.
I've tried various combinations of foreach solutions but I'm not getting anywhere. I thought a while loop would be more suitable but I don't know what condition to test for.
Any ideas please?!
I would loop through your data and create a dictionary where the keys are the user ids, and the values are the appropriate user objects with the sport appended. Then you can reconstruct your example data array structure by looping through this de-duped array using the sport data to determine where to put each user.
To create the de-duped array, use something like:
$deDupedData = array();
foreach ($data as $sport => $users) {
foreach ($users as $user) {
if (isset($deDupedData[$user->id])) {
if ($user->points > $deDupedData[$user->id]->points) {
$deDupedData[$user->id]->sport = $sport;
$deDupedData[$user->id]->points = $user->points;
}
} else {
$modifiedUser = $user;
$modifiedUser->sport = $sport;
$deDupedData[$user->id] = $modifiedUser;
}
}
}
// Now reconstruct your array...

Categories