Parsing a nested array where key is a float in php - php

I have the following query that I need to get a value from a nested array. I'm using laravel 5.4 in case that matters.
$usersstyle = DB::connection('mysql2')
->table('wp_rg_lead_detail')
->where('lead_id', $collection->id)
->get();
dd($usersstyle);
This has an output of:
Collection {#396 ▼
#items: array:49 [▼
0 => {#406 ▶}
1 => {#407 ▶
18 => {#428 ▼
+"id": 655
+"lead_id": 67
+"form_id": 8
+"field_number": 51.0
+"value": "Yes"
}
19 => {#429 ▼
+"id": 656
+"lead_id": 67
+"form_id": 8
+"field_number": 6.1
+"value": "Sleeveless"
}
20 => {#430 ▼
+"id": 657
+"lead_id": 67
+"form_id": 8
+"field_number": 6.2
+"value": "Jacket"
}
21 => {#431 ▼
+"id": 658
+"lead_id": 67
+"form_id": 8
+"field_number": 6.3
+"value": "Cardigan"
}
22 => {#432 ▶}
I have tried the following, but it returns the 1st instance of the field_number, and ignores the 6.2 and 6.3. How do I do this and keep all the floats as keys.
$keyed = $usersstyle->keyBy('field_number')->all();
I want to get something like the below. With out a foreach loop to display that.
echo $6.3->value;
with the result being Cardigan
I have also used
$grabvalues = $usersstyle->whereIn('field_number', 80.3)->toArray();
this returns an array or if i drop the toArray a collection that I still need to loop through to get the value

Try this : This doc may help you .
$plucked = $usersstyle->pluck('field_number', 'value');
$plucked->all();
Another way :
$fieldValue = $usersstyle->map(function ($users) {
return collect($users->toArray())
->only(['field_number', 'value'])
->all();
});

Well after a bunch of test.. Here is the answer I came up with that worked for me. if someone knows how to write this better please submit.
$usersstyle = DB::connection('mysql2')
->table('wp_rg_lead_detail')
->where('lead_id', $collection->id)
->get()
;
$newkeys = $usersstyle->pluck('field_number');
$values = $usersstyle->pluck('value');
$result = $newkeys->combine($values)->toArray();
dd($result["6.1"]);

Related

remove duplicates from a group of arrays

I have the following group of arrays in one array, where the content of them is a group of posts :
array:5 [▼
"in" => array:2 [▼
0 => {#371 ▼
+"id": 61
+"created_at": "2019-11-29 08:12:11"
+"updated_at": "2019-11-29 08:12:11"
+"title": "Sports test "
+"body": "Test answer"
+"ttype": 0
+"cat": 0
+"a_id": 61
+"tag": ""
}
1 => {#372 ▶}
]
"out" => []
"other" => []
"fol" => array:17 [▶]
"tag" => []
]
The arrays :
$Final_updts['in'] = $all_update_in;
$Final_updts['out'] = $all_update_out;
$Final_updts['other'] = $all_update_oth;
$Final_updts['fol'] = $follow_psts;
$Final_updts['tag'] = $post_tags;
There might be some posts repeated in more than one array. I tried to use array_unique($Final_updts);, but received Error exception: Array to string conversion
Is there any easy way to do this, or I have to modify the 5 queries to prevent any duplicate results ?
I assume that you want to get unique items by id. Lets use collection to solve this problem.
$results = collect($array)->collapse()->unique('id');
Pls let me know if I got it right.

PHP, array of objects, how can I use one set of object values as the array keys [duplicate]

This question already has answers here:
Get two columns of data as an array of keys and values using Laravel
(2 answers)
Closed 7 months ago.
I have an array that looks like this:
array:9 [▼
0 => {#279 ▼
+"id": "103"
+"name": "In what city did you meet your spouse/partner?"
}
1 => {#280 ▼
+"id": "100"
+"name": "What is the first name of the person you first kissed?"
}
2 => {#281 ▼
+"id": "102"
+"name": "What is the name of your favorite childhood friend?"
}
3 => {#282 ▶}
4 => {#283 ▶}
5 => {#284 ▶}
6 => {#285 ▶}
7 => {#286 ▶}
8 => {#287 ▶}
]
This is the dd(). I'm wondering how it might be possible to transform it into a key/value array, using the id as the key and the name as the value. Something like this:
array(
'103' => 'In what city did you meet your spouse/partner?',
'100' => 'What is the first name of the person you first kissed?'
);
As of PHP 7, you can use array_column() on objects, with the third parameter as the column to index by...
$questions = array_column($data, "name", "id");
You can use a collections pluck method:
$collection = collect($array)->pluck("name","id");
If you want to get an array back use:
$collection->all();
I figured it out with:
$data = DB::connection()->select($sql);
$questions = [];
foreach ($data as $question) {
$questions[$question->id] = $question->name;
}
Open to any slicker solutions, but this definitely works!

Using Laravel to average values, group by a category and a date range, and show the output on a single page

I have a table that looks something like this:
I want to be able to query this table and display results based on grouping by subject and by date. The dates would satisfy a range (between x and y).
I am looking to output something like this:
Term 1 - Art - (average of all asssessed_level for x range)
Term 2 - Art - (average of all asssessed_level for y range)
Term 3 - Art - (average of all asssessed_level for z range)
And this:
Term 1 - Math - (average of all asssessed_level for x range)
Term 2 - Math - (average of all asssessed_level for y range)
Term 3 - Math - (average of all asssessed_level for z range)
(etc.)
If there is no assessed_level for a date range, then I still need it to return a subject with perhaps an 'N/A' for that spot.
Ultimately, I want a table of data that will look something like this:
('E' would be where the average assessed_level goes and the YEAR column would be a result that is averaged and ignores the date range)
This is the code that I have written, but it doesn't provide the results that I need:
for($b=0; $b < $assessed_subjects->count(); $b++) {
$assessment_strengths[] = DB::table('assessment_data')
->join('subjects', 'assessment_data.subject_id', '=', 'subjects.id')
->join('units', 'assessment_data.unit_id', '=', 'units.id')
->join('outcomes', 'assessment_data.outcome_id', '=', 'outcomes.id')
->join('assessments', 'assessment_data.assessment_id', '=', 'assessments.id')
->select('subjects.short_name as subject_name', 'units.name as unit_name', 'outcomes.name as outcome_name', 'assessments.assessment_name as assessment_name', 'assessment_data.*')
->where('assessment_data.user_id', 28)
->where('assessment_data.student_id', $student_id)
->where('assessment_data.subject_id', $assessed_subjects[$b]->id)
->whereBetween('assessment_data.created_at', [$current_term->term_start, $current_term->term_end])
->orderBy('assessment_data.assessed_level', 'desc')
->get();
}
This is the output that I get when I dd() the query:
array:8 [▼
0 => Collection {#371 ▼
#items: []
}
1 => Collection {#386 ▼
#items: []
}
2 => Collection {#392 ▼
#items: array:1 [▼
0 => {#390 ▼
+"subject_name": "Math"
+"unit_name": "Rocks and Minerals"
+"outcome_name": "Analyze how positive health habits can be supported by a variety of approaches to health practices and treatments"
+"assessment_name": "The First Assessment"
+"id": 36
+"user_id": 28
+"room_id": 1
+"assessment_id": 1
+"student_id": 6
+"subject_id": 19
+"unit_id": 188
+"outcome_id": 476
+"assessed_level": 4.0
+"created_at": "2018-03-29 10:04:42"
+"updated_at": "2018-03-29 10:04:42"
}
]
}
3 => Collection {#399 ▼
#items: array:1 [▼
0 => {#397 ▼
+"subject_name": "Social"
+"unit_name": "Animals"
+"outcome_name": "Demonstrate and explain the effect of adding zero to, or subtracting zero from, any number."
+"assessment_name": "The First Assessment"
+"id": 48
+"user_id": 28
+"room_id": 1
+"assessment_id": 1
+"student_id": 6
+"subject_id": 25
+"unit_id": 122
+"outcome_id": 27
+"assessed_level": 4.0
+"created_at": "2018-01-01 10:04:42"
+"updated_at": "2018-03-29 10:04:42"
}
]
}
4 => Collection {#406 ▼
#items: []
}
5 => Collection {#412 ▼
#items: []
}
6 => Collection {#418 ▼
#items: array:1 [▼
0 => {#416 ▼
+"subject_name": "ELA"
+"unit_name": "Explore - Clarify and Extend"
+"outcome_name": "State, orally in their own words, that in French the indefinite article is not used when identifying one’s profession (e.g., m. brown est dentiste.)"
+"assessment_name": "The First Assessment"
+"id": 18
+"user_id": 28
+"room_id": 1
+"assessment_id": 1
+"student_id": 6
+"subject_id": 6
+"unit_id": 25
+"outcome_id": 3000
+"assessed_level": 4.0
+"created_at": "2018-03-29 10:04:42"
+"updated_at": "2018-03-29 10:04:42"
}
]
}
7 => Collection {#425 ▼
#items: []
}
]
As you can see, there are empty values (0, 1, 4, 5, 7) that I would like to push some data to. I took a look at IFNULL and COALESCE as a way of providing a fall-back, but that wasn't helpful in this case. Is there a way to append (or something like that) values into query results, even if they are otherwise empty?
My thought process is that if I can define each of the records that are being output as belonging to a specific term, I will be closer to having what I need.
I would suggest an approach like this:
$result = [];
foreach($assessed_subjects as $subject) {
$query = DB::table('assessment_data')
->select(DB::raw('avg(`assessed_level`) as `avg`'))
->where('user_id', 28)
->where('student_id', $student_id)
->where('subject_id', $subject->subject_id);
foreach($user_terms as $term) {
$result[$subject->subject_id][$term->id] = (clone $query)
->whereBetween('created_at', [$term->term_start, $term->term_end])
->first()->avg;
}
$result[$subject->subject_id]['year'] = (clone $query)
->whereBetween('created_at', [$user_terms->first()->term_start, $user_terms->last()->term_end])
->first()->avg;
}
This gives you the average level grouped by subject and term. If there is no value, it's NULL.
Or an alternative solution with fewer queries:
$result = [];
$query = DB::table('assessment_data')
->select('subject_id', DB::raw('avg(`assessed_level`) as `avg`'))
->where('user_id', 28)
->where('student_id', $student_id)
->whereIn('subject_id', $assessed_subjects->pluck('subject_id'))
->groupBy('subject_id');
foreach($user_terms as $term) {
$rows = (clone $query)
->whereBetween('created_at', [$term->term_start, $term->term_end])
->get();
foreach($rows as $row) {
$result[$row->subject_id][$term->id] = $row->avg;
}
}
$rows = (clone $query)
->whereBetween('created_at', [$user_terms->first()->term_start, $user_terms->last()->term_end])
->get();
foreach($rows as $row) {
$result[$row->subject_id]['year'] = $row->avg;
}
The only disadvantage is that it doesn't add NULL values for missing averages to the result.

Getting Undefined property: stdClass::$options when using a foreach on an array

I have an PHP object - $new_step.
In Laravel, if I dd on a child object that is an array - dd($new_step->data->options); - of it, I get a valid entry:
array:5 [▼
0 => {#695 ▼
+"position": 1
+"value": "Dogs"
}
1 => {#694 ▼
+"position": 2
+"value": "Cats"
}
2 => {#693 ▼
+"position": 3
+"value": "Ferretts"
}
3 => {#669 ▼
+"position": 4
+"value": "Gophers"
}
4 => {#665 ▼
+"position": 5
+"value": "Possum"
}
]
However, when I try to do a foreach on the object:
foreach ($new_step->data->options as $options) {
$options->count = 0;
}
I get this error:
ErrorException
Undefined property: stdClass::$options
Why does the foreach fail?
Turns out that there was an array in the iteration that was an object and not an array. To test, I moved the for loop further out of the chain and tested each iteration thru it to see that the 5th iteration was the one responsible for causing the error.
To do that foreach you must store a result of Object in the variable.
$temp = $new_step->data->options;
foreach ($temp as $options) {
$options->count = 0;
}
At the end, you will get in your list count variable for each array as you want?
Do dd($temp) below foreach to check result.
If you again don't get right array probably you have some bug in $new_step->data->options.

Loop through JSON array to get score - Laravel 5.2

I'am having problem looping through an array to get every teams score for the last 10 games played by a player. This is how I'm looping through this array:
$WarzoneLast10MatchesTeamScore = [];
foreach($warzoneLast10matches->Results->Teams as $idx => $stats){
$WarzoneLast10MatchesTeamScore[$idx]['Score'] = $stats->Score;
$WarzoneLast10MatchesTeamScore[$idx]['Id'] = $stats->Id;
}
The problem with this is it will give me an error because I'am trying to get the last 10 games played, so result has to be then Result[0], Result[1], and so on.
Here is what I mean:
+"Results": array:10 [▼
0 => {#17371 ▼
+"Links": {#13129 ▶}
+"Id": {#13130 ▶}
+"HopperId": "0e39ead4-383b-4452-bbd4-babb7becd82e"
+"MapId": "c89dae21-f206-11e4-a1c2-24be05e24f7e"
+"MapVariant": {#13121 ▶}
+"GameBaseVariantId": "42f97cca-2cb4-497a-a0fd-ceef1ba46bcc"
+"GameVariant": {#17372 ▶}
+"MatchDuration": "PT6M50.2813116S"
+"MatchCompletedDate": {#17367 ▶}
+"Teams": array:2 [▼
0 => {#17374 ▼
+"Id": 0
+"Score": 1
+"Rank": 1
}
1 => {#17375 ▼
+"Id": 1
+"Score": 0
+"Rank": 2
}
]
+"Players": array:1 [▶]
+"IsTeamGame": true
+"SeasonId": null
+"MatchCompletedDateFidelity": 1
}
1 => {#17378 ▶}
2 => {#17390 ▶}
3 => {#17402 ▶}
4 => {#17414 ▶}
5 => {#17426 ▶}
6 => {#17438 ▶}
7 => {#17450 ▶}
8 => {#17462 ▶}
9 => {#17474 ▶}
]
I obviously don't want to make 10 loops for each game then hard code the score for each game in my view.
How can I loop through the Results object, and then get the Teams->score and Teams->Id objects?
FYI
I know I can use collections like this:
public function getWarzoneLast10Matches($warzoneLast10matches) {
// Collect al the results for this array
$results = collect($warzoneLast10matches->Results);
$array = $results->map(function($item, $key) {
return [
'Gamertag' => $item->Players[0]->Player->Gamertag,
'MapId' => $item->MapId,
'GameBaseVariantId' => $item->GameBaseVariantId,
'Score' => $item->Teams[0]->Score,
'Score2' => $item->Teams[1]->Score,
'Id' => $item->Teams[0]->Id,
'Id2' => $item->Teams[1]->Id,
];
});
return $array;
}
But this will not work because in some games there is only 1 team, and if that happens, then it will throw me an error saying undefined offset 1, because there is no team 2. The other method I'am using on top wont give me errors.
It sound like you might need to make your function recursive.
Learn more about Recursion

Categories