0

This is my JSON output:

array:2 [
    0 => "[{"subject":"Science","date":"2018-08-09 13:03:14","average":4},{"subject":"Science","date":"2018-09-13 13:18:58","average":4}]"
    1 => "[{"subject":"Social","date":"2018-08-14 05:59:56","average":4}]"
]

What I want:

[{"subject":"Science","date":"2018-08-09 13:03:14","average":4},{"subject":"Science","date":"2018-09-13 13:18:58","average":4},{"subject":"Social","date":"2018-08-14 05:59:56","average":4}]

I am not certain how to achieve this. I have tried array_merge, array_combine, array_map, json_encode, json_decode—and various combinations of them all! I am obviously missing something.

Here's my code:

// $classroom_subjects references a table, listing subjects
// for each subject, get the assessment data
foreach ($classroom_subjects as $subject) {
    $loop_graph_data[] = AssessmentData::select('subjects.short_name as subject', 'assessment_data.created_at as date', 'assessment_data.assessed_level as average')
        ->join('subjects', 'subjects.id', 'assessment_data.subject_id')
        ->where('assessment_data.subject_id', $subject->subject_id)
        ->where('assessment_data.student_id', $student_id)
        ->whereBetween('assessment_data.created_at', [$current_term->term_start." 00:00:01", $current_term->term_end." 23:59:59"])
        ->get()
        ->toJson();
}

// create an empty variable
$kept_data = [];

// loop through each of the assessment_data elements and only
// keep the one's that have data (no empty arrays)
foreach($loop_graph_data as $graph_data) {
    if ($graph_data != "[]") {
        $kept_data[] = $graph_data;
    }
}

I want to "join" the two (or more—this is dynamic) arrays together into one seamless JSON formatted string.

Does someone know how to do this?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Sheldon Scott
  • 741
  • 1
  • 7
  • 21

3 Answers3

0

Something like json_encode(array_merge(json_decode($a, true),json_decode($b, true))) should work.

do inside your foreach

please refer to this similar issue: Merging two json in PHP

manu
  • 351
  • 2
  • 15
0

I ended up having to double array_flatten the data. Here's the solution I've used:

// get all the data for making a graph
// it needs to be compiled by subject
foreach ($classroom_subjects as $subject) {
    $loop_graph_data[] = AssessmentData::select('subjects.short_name as subject', 'assessment_data.created_at as date', 'assessment_data.assessed_level as average')
        ->join('subjects', 'subjects.id', 'assessment_data.subject_id')
        ->where('assessment_data.subject_id', $subject->subject_id)
        ->where('assessment_data.student_id', $student_id)
        ->whereBetween('assessment_data.created_at', [$current_term->term_start." 00:00:01", $current_term->term_end." 23:59:59"])
        ->get();
}

$kept_data = [];
foreach($loop_graph_data as $graph_data) {
    if ($graph_data != "[]") {
        $kept_data[] = $graph_data;
    }
}

$flattened = array_flatten(array_flatten($kept_data));
$flattened = json_encode($flattened);

dd($flattened);

Output:

[{"subject":"Science","date":"2018-08-09 13:03:14","average":4},{"subject":"Science","date":"2018-09-13 13:18:58","average":4},{"subject":"Social","date":"2018-08-14 05:59:56","average":4}]

Sheldon Scott
  • 741
  • 1
  • 7
  • 21
0

If I am not misunderstanding, you just need to filter earlier and not keep pushing more depth into your data structure.

$loop_graph_data = [];
foreach ($classroom_subjects as $subject) {
    array_push(
        $loop_graph_data,
        ...array_filter(
            AssessmentData::select('subjects.short_name as subject', 'assessment_data.created_at as date', 'assessment_data.assessed_level as average')
                ->join('subjects', 'subjects.id', 'assessment_data.subject_id')
                ->where('assessment_data.subject_id', $subject->subject_id)
                ->where('assessment_data.student_id', $student_id)
                ->whereBetween('assessment_data.created_at', [$current_term->term_start." 00:00:01", $current_term->term_end." 23:59:59"])
                ->get(),
            fn($graph_data) => $graph_data !== "[]"
        )
    )
}

This approach can push more than one element at a time and will keep the result array flat.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136