PHP - split array from query - php

I am using PHP and I have array from query
Array
(
[0] => stdClass Object
(
[question_id] => 13
[is_break] => 0
)
[1] => stdClass Object
(
[question_id] => 14
[is_break] => 1
)
[2] => stdClass Object
(
[question_id] => 15
[is_break] => 0
)
[3] => stdClass Object
(
[question_id] => 16
[is_break] => 1
)
[4] => stdClass Object
(
[question_id] => 17
[is_break] => 1
)
)
How to split (grouping) by is_break = 1 so i have question_id (13,14)(15,16)(17)

A simple and naive solution might look something like this:
var original = /* your original array, the one you posted */;
var result = [];
var tmp = [];
$.each(original, function(idx, obj) {
tmp.push(obj.question_id);
if(obj.is_break == 1) {
result.push(tmp);
tmp = [];
}
});
console.log(result); // returns array of array
HTH
EDIT: In PHP, it may look something like this (I am not too well-versed in PHP):
var $original = /* your original array, the one you posted */;
var $result = [];
var $tmp = [];
foreach($original as $obj) {
$tmp.push($obj.question_id); /* or could be $obj['question_id'] */
if($obj.is_break == 1) { /* or could be $obj['is_break'] */
$result.push($tmp);
$tmp = [];
}
});

Here's solution
$data = {your data};
$result = array();
$i = 0;
foreach($data as $k => $item) {
if ($item->is_break) {
$result[] = array_slice($data, $i, $k);
}
$i = $k;
}
print_r($result);

Try this:
<?php
$inputArr = Array
(
Array("question_id" => 13, "is_break" => 0),
Array("question_id" => 14, "is_break" => 1),
Array("question_id" => 15, "is_break" => 0),
Array("question_id" => 16, "is_break" => 1),
Array("question_id" => 17, "is_break" => 1)
);
$result = array();
$tmp = array();
foreach ($inputArr as $obj) {
//$tmp . push($obj . question_id); /* or could be $obj['question_id'] */
array_push($tmp, $obj['question_id']);
if ($obj['is_break'] == 1) { /* or could be $obj['is_break'] */
//$result . push($tmp);
array_push($result, $tmp);
$tmp = array();
}
}
var_dump($result);
?>
Thanks

Related

php remove empty 'columns' in multidimensional, associative array

Goal: Generate an array that includes only those 'columns' with data, even though a 'header' may exist.
Example Data:
Array (
[HeaderRow] => Array (
[0] => Employee [1] => LaborHours [2] => 0.1 [3] => 0.25 [4] => 0.5 [5] => 0.8
)
[r0] => Array (
[0] => Joe [1] => 5 [2] => [3] => [4] => 50 [5] =>
)
[r1] => Array (
[0] => Fred [1] => 5 [2] => 10 [3] => [4] => [5] =>
)
)
Desired Output:
Array (
[HeaderRow] => Array (
[0] => Employee [1] => LaborHours [2] => 0.1 [4] => 0.5
)
[r0] => Array (
[0] => Joe [1] => 5 [2] => [4] => 50
)
[r1] => Array (
[0] => Fred [1] => 5 [2] => 10 [4] =>
)
)
So, in this very dumbed down example, the HeaderRow will always have data, but if both c0 and c1 are empty (as is the case for [3] and [5]) then I want to remove. I tried iterating through with for loops like I would in other languages, but that apparently doesn't work with associative arrays. I then tried doing a transpose followed by two foreach loops, but that failed me as well. Here's a sample of my for loop attempt:
Attempt with For Loop
for ($j = 0; $j <= count(reset($array))-1; $j++) {
$empty = true;
for ($i = 1; $i <= count($array)-1; $i++) {
if(!empty($array[$i][$j])) {
$empty = false;
break;
}
}
if ($empty === true)
{
for ($i = 0; $i <= count($array); $i++) {
unset($array[$i][$j]);
}
}
}
return $array;
Attempt with transpose:
$array = transpose($array);
foreach ($array as $row)
{
$empty = true;
foreach ($row as $value)
{
if (!empty($value))
{
$empty = false;
}
}
if ($empty) {
unset($array[$row]);
}
}
$array = transpose($array);
return $array;
function transpose($arr) {
$out = array();
foreach ($arr as $key => $subarr) {
foreach ($subarr as $subkey => $subvalue) {
$out[$subkey][$key] = $subvalue;
}
}
return $out;
}
I know the transpose one isn't terribly fleshed out, but I wanted to demonstrate the attempt.
Thanks for any insight.
We can make this more simpler. Just get all column values using array_column.
Use array_filter with a custom callback to remove all empty string values.
If after filtering, size of array is 0, then that key needs to be unset from all
subarrays.
Note: The arrow syntax in the callback is introduced since PHP 7.4.
Snippet:
<?php
$data = array (
'HeaderRow' => Array (
'0' => 'Employee','1' => 'LaborHours', '2' => 0.1, '3' => 0.25, '4' => 0.5, '5' => 0.8
),
'r0' => Array (
'0' => 'Joe', '1' => 5, '2' => '','3' => '', '4' => 50, '5' => ''
),
'r1' => Array (
'0' => 'Fred', '1' => 5,'2' => 10, '3' => '', '4' => '', '5' => ''
)
);
$cleanup_keys = [];
foreach(array_keys($data['HeaderRow']) as $column_key){
$column_values = array_column($data, $column_key);
array_shift($column_values); // removing header row value
$column_values = array_filter($column_values,fn($val) => strlen($val) != 0);
if(count($column_values) == 0) $cleanup_keys[] = $column_key;
}
foreach($data as &$row){
foreach($cleanup_keys as $ck){
unset($row[ $ck ]);
}
}
print_r($data);
It figures, I work on this for a day and have a moment of clarity right after posting. The answer was that I wasn't leveraging the Keys.:
function array_cleanup($array)
{
$array = transpose($array);
foreach ($array as $key => $value)
{
$empty = true;
foreach ($value as $subkey => $subvalue)
{
if ($subkey != "HeaderRow") {
if (!empty($subvalue))
{
$empty = false;
}
}
}
if ($empty) {
unset($array[$key]);
}
}
$array = transpose($array);
return $array;
}

Grouping data in ChartJS and PHP

Hi have a data table which i am trying to draw a graph of using ChartJS. The data array looks like below
Array
(
[0] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P1
[Count] => 7
)
[1] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P2
[Count] => 3
)
[2] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P3
[Count] => 4
)
[3] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P4
[Count] => 3
)
[4] => Array
(
[Sort] => 3
[Weeks] => 2-3 weeks
[Severity] => P1
[Count] => 1
)
[5] => Array
(
[Sort] => 4
[Weeks] => >4 weeks
[Severity] => No Value
[Count] => 1
)
[6] => Array
(
[Sort] => 4
[Weeks] => >4 weeks
[Severity] => P1
[Count] => 1
)
[7] => Array
(
[Sort] => 4
[Weeks] => >4 weeks
[Severity] => P3
[Count] => 1
)
)
I converted that array compatible with ChartJS like below
Array
(
[labels] => Array
(
[0] => >4 weeks
[1] => 2-3 weeks
[2] => 1-2 Weeks
)
[datasets] => Array
(
[0] => Array
(
[label] => No Value
[backgroundColor] => #F00
[borderColor] => #F00
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 1
)
)
[1] => Array
(
[label] => P1
[backgroundColor] => #84a4d4
[borderColor] => #84a4d4
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 1
[1] => 1
[2] => 7
)
)
[2] => Array
(
[label] => P3
[backgroundColor] => #eb8d22
[borderColor] => #eb8d22
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 1
[1] => 4
)
)
[3] => Array
(
[label] => P2
[backgroundColor] => #FBCEB1
[borderColor] => #FBCEB1
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 3
)
)
[4] => Array
(
[label] => P4
[backgroundColor] => #7FFFD4
[borderColor] => #7FFFD4
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 3
)
)
)
)
But the data gets scrambled when it is plotted to Chart. The data gets arranged like this
This is the real data and how the graph should look like
Here is my code
function chart(){
$ar= RNCPHP\AnalyticsReport::fetch('Open tickets Ageing by priority');
$arr= $ar->run(0, $filters);
$chartInit = array();
$chartArr['data'] = array();
// push the report data into an array
for ( $ii = $arr->count(); $ii--; ) {
$row = $arr->next();
if($row['Severity'] == null || $row['Severity'] == "") {
$row['Severity'] = "No Value";
}
$row['Sort'] = $row['Sort'];
array_push($chartInit, $row);
}
echo "<pre>";
print_r($chartInit);
array_multisort(array_map(function($element) {
return $element['Sort'];
}, $chartInit), SORT_DESC, $chartInit);
$chartDataArr = array();
$sevArr = array();
foreach($chartInit as $k => $v) {
if(!isset($chartDataArr[$v['Weeks']])) {
$chartDataArr[$v['Weeks']] = array();
}
array_push($chartDataArr[$v['Weeks']], $v);
if(!in_array($v['Severity'], $sevArr)) {
array_push($sevArr, $v['Severity']);
}
}
$mapLabels = array();
$parsedAry = array();
$parsedAry['labels'] = array();
$parsedAry['datasets'] = array();
for($i = 0; $i < count($sevArr); $i++) {
$parsedAry['datasets'][$i] = array();
$parsedAry['datasets'][$i]['label'] = $sevArr[$i];
$parsedAry['datasets'][$i]['backgroundColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderWidth'] = 1;
$parsedAry['datasets'][$i]['maxBarThickness'] = 50;
$parsedAry['datasets'][$i]['data'] = array();
}
foreach($chartDataArr as $k => $v) {
array_push($parsedAry['labels'], $k);
foreach($v as $k1 => $v1) {
$keySev = "";
foreach($parsedAry['datasets'] as $k2 => $v2) {
if($v2['label'] == $v1['Severity']) {
$keySev = $k2;
}
}
if($v1['Count'] == null || $v1['Count'] == "") {
$v1['Count'] = 0;
}
array_push($parsedAry['datasets'][$keySev]['data'], $v1['Count']);
}
}
echo "<pre>";
print_r($parsedAry);
echo "</pre>";
$chartArr['data'] = $parsedAry;
return $chartArr;
}
In my view page i'm displaying data with ChartJS Function
<canvas id="chart6"></canvas>
<script>
var ctx = document.getElementById('chart6').getContext('2d');
var data = <?php echo $data ?>;
var drawChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 1
}
}]
},
title: {
display: true,
text: 'Open tickets Ageing by priority'
}
}
});
</script>
Please Help.
Your code has several problems.
First, your datasets should has data in numbers of labels so you can't ignore empty places without filling them. To fix this problem you need to change
$parsedAry['datasets'][$i]['data'] = array(); to $parsedAry['datasets'][$i]['data'] = array(0, 0, 0, 0, 0);
This will add 5 empty spot in your datasets.
Second you have to put numbers in right places for this one you have to add a counter for your last loop to identify right places.
Finally your code should look like this.
function chart()
{
$ar = RNCPHP\AnalyticsReport::fetch('Open tickets Ageing by priority');
$arr = $ar->run(0, $filters);
$chartInit = array();
$chartArr['data'] = array();
// push the report data into an array
for ($ii = $arr->count(); $ii--;) {
$row = $arr->next();
if ($row['Severity'] == null || $row['Severity'] == "") {
$row['Severity'] = "No Value";
}
$row['Sort'] = $row['Sort'];
array_push($chartInit, $row);
}
echo "<pre>";
print_r($chartInit);
array_multisort(array_map(function ($element) {
return $element['Sort'];
}, $chartInit), SORT_DESC, $chartInit);
$chartDataArr = array();
$sevArr = array();
foreach ($chartInit as $k => $v) {
if (!isset($chartDataArr[$v['Weeks']])) {
$chartDataArr[$v['Weeks']] = array();
}
array_push($chartDataArr[$v['Weeks']], $v);
if (!in_array($v['Severity'], $sevArr)) {
array_push($sevArr, $v['Severity']);
}
}
$mapLabels = array();
$parsedAry = array();
$parsedAry['labels'] = array();
$parsedAry['datasets'] = array();
for ($i = 0; $i < count($sevArr); $i++) {
$parsedAry['datasets'][$i] = array();
$parsedAry['datasets'][$i]['label'] = $sevArr[$i];
$parsedAry['datasets'][$i]['backgroundColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderWidth'] = 1;
$parsedAry['datasets'][$i]['maxBarThickness'] = 50;
$parsedAry['datasets'][$i]['data'] = array(0, 0, 0, 0, 0);
}
$labelsNo = 0;
foreach ($chartDataArr as $k => $v) {
array_push($parsedAry['labels'], $k);
foreach ($v as $k1 => $v1) {
$keySev = "";
foreach ($parsedAry['datasets'] as $k2 => $v2) {
if ($v2['label'] == $v1['Severity']) {
$keySev = $k2;
}
}
if ($v1['Count'] == null || $v1['Count'] == "") {
$v1['Count'] = 0;
}
$parsedAry['datasets'][$keySev]['data'][$labelsNo] = $v1['Count'];
}
$labelsNo++;
}
echo "<pre>";
print_r($parsedAry);
echo "</pre>";
$chartArr['data'] = $parsedAry;
return $chartArr;
}

How to transform array to this json pattern?

I have array something like this
Array
(
[0] => Array
(
[product_id] => 13
[unit] => 1
[price] => 20.0000
[total] => 20.0000
)
[1] => Array
(
[product_id] => 15
[unit] => 2
[price] => 30.0000
[total] => 10.0000
)
)
I was stuck to transform above array to the "ProductList" in the following pattern
array(
"UserID" => 2,
"ProductList" => [
{
"ProductID"=> 13,
"Price"=> 20.0000
},
{
"ProductID"=> 15,
"Price"=> 30.0000
}
]
)
I tried like this:
$products = [];
foreach($items as $item) {
if(!empty($item['product_id'])) {
$product = '{"ProductID"=>' . $item['product_id'] . '}';
$products[] = $product;
}
}
But not the expected result.
You're looking for json_encode(): http://php.net/manual/en/function.json-encode.php
Assign your array to a variable, for example $products, and then you can simply write json_encode($products) to achieve your desired result.
Try this,
$prodlist = array();
$x = 0;
foreach($arrs as $arr) {
//if ($arr['product_id'] == "" && $arr['price'] == "") continue;
$prodlist[$x]['Price'] = $arr['price'];
$prodlist[$x]['ProductID'] = $arr['product_id'];
$x += 1;
}
$arr2return['user_id'] = $user_id;
$arr2return['ProductList'] = $prodlist;
json_encode($arr2return);

count the duplicate “usuario_cidade” in multi-dimensional

please help me with a code. I have this multi-dimensional array and need to count the value of usuario_cidade case its same value like this:
array 52 = (2) Cidade_1, (2) Cidade_2, (1) Cidade_3
Array
(
[52] => Array
(
[0] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_1
)
[1] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_1
)
[2] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_2
)
[3] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_3
)
[4] => stdClass Object
(
[funcionario_id] => 52
[usuario_cidade] => Cidade_2
)
)
)
Try this code:
//Create object array format as per question scenario for testing...
$arrObject1 = new stdClass();
$arrObject1->funcionario_id = '52';
$arrObject1->usuario_cidade = 'Cidade_1';
$arrObject2 = new stdClass();
$arrObject2->funcionario_id = '52';
$arrObject2->usuario_cidade = 'Cidade_1';
$arrObject3 = new stdClass();
$arrObject3->funcionario_id = '52';
$arrObject3->usuario_cidade = 'Cidade_2';
$arrObject4 = new stdClass();
$arrObject4->funcionario_id = '52';
$arrObject4->usuario_cidade = 'Cidade_3';
$arrObject5 = new stdClass();
$arrObject5->funcionario_id = '52';
$arrObject5->usuario_cidade = 'Cidade_2';
//Finalize array...
$varArray = array('52' => array(
$arrObject1, $arrObject2, $arrObject3, $arrObject4, $arrObject5
));
$arrResult = array();
//Loop until main array...
foreach($varArray AS $arrKey => $arrObjVal){
//Loop for object values...
foreach($arrObjVal AS $ocjKey => $objVal){
//Check for specific key(i.e. value of usuario_cidade) exist into result array...
if(array_key_exists($objVal->usuario_cidade, $arrResult)){
//Increment value if exist...
$arrResult[$objVal->usuario_cidade] = $arrResult[$objVal->usuario_cidade] + 1;
}
else {
//Initialize value of result array...
$arrResult[$objVal->usuario_cidade] = 1;
}
}
}
print('<pre>');
print_r($arrResult);
print('</pre>');
This will give result:
[Cidade_1] => 2
[Cidade_2] => 2
[Cidade_3] => 1
Hope this help you!
Try this..
$your_array = array();
$usuario_cidade = array();
foreach ($your_array as $key => $values){
foreach($values as $value){
$usuario_cidade[$key][$value->usuario_cidade]=isset($usuario_cidade[$key][$value->usuario_cidade]) ? $usuario_cidade[$key][$value->usuario_cidade] : '0' + 1;
}
}
print_r($usuario_cidade);
Hey kindly check this code it is given the same answer as the conditions are given.
$arr = array();
$arr2 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_1' );
$arr3 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_1' );
$arr4 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_2' );
$arr5 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_3' );
$arr6 = array('funcionario_id' => 52,'usuario_cidade' => 'Cidade_2' );
$arr = [$arr2,$arr3,$arr4,$arr5,$arr6];
$cidaed = array('Cidade_1' => 0, 'Cidade_2' => 0 , 'Cidade_3' => 0 );
$count = 0;
//echo var_dump($arr);
foreach ($arr as $key => $value) {
foreach ($value as $keys => $values) {
if($keys == 'usuario_cidade')
{
$cidaed[$values] += 1;
}
}
}
echo var_dump($cidaed);
The answer for above will be.
array(3) { ["Cidade_1"]=> int(2) ["Cidade_2"]=> int(2) ["Cidade_3"]=> int(1) }
Can you please check this.
$main_array[52] = array(
0 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_1'
),
1 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_1'
),
2 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_2'
),
3 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_3'
),
4 => array(
'funcionario_id' => 52,
'usuario_cidade' => 'Cidade_2'
)
);
$check_array = array();
$count_array = array();
foreach ($main_array as $main){
foreach($main as $data){
if(in_array($data['usuario_cidade'], $check_array)){
$count_array[$data['usuario_cidade']] = $count_array[$data['usuario_cidade']] + 1;
}else{
array_push($check_array,$data['usuario_cidade']);
$count_array[$data['usuario_cidade']] = 1;
}
}
}
foreach($count_array as $key => $value){
echo $key.'='.$value.'<br />';
}
echo "<pre>"; print_r($count_array);

PHP Counting inside an Array

I want to create a list where if its already in the array to add to the value +1.
Current Output
[1] => Array
(
[source] => 397
[value] => 1
)
[2] => Array
(
[source] => 397
[value] => 1
)
[3] => Array
(
[source] => 1314
[value] => 1
)
What I want to Achieve
[1] => Array
(
[source] => 397
[value] => 2
)
[2] => Array
(
[source] => 1314
[value] => 1
)
My current dulled down PHP
foreach ($submissions as $timefix) {
//Start countng
$data = array(
'source' => $timefix['parent']['id'],
'value' => '1'
);
$dataJson[] = $data;
}
print_r($dataJson);
Simply use an associated array:
$dataJson = array();
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (!isset($dataJson[$id])) {
$dataJson[$id] = array('source' => $id, 'value' => 1);
} else {
$dataJson[$id]['value']++;
}
}
$dataJson = array_values($dataJson); // reset the keys - you don't nessesarily need this
This is not exactly your desired output, as the array keys are not preserved, but if it suits you, you could use the item ID as the array key. This would simplify your code to the point of not needing to loop through the already available results:
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (array_key_exists($id, $dataJson)) {
$dataJson[$id]["value"]++;
} else {
$dataJson[$id] = [
"source" => $id,
"value" => 1
];
}
}
print_r($dataJson);
You should simplify this for yourself. Something like:
<?
$res = Array();
foreach ($original as $item) {
if (!isset($res[$item['source']])) $res[$item['source']] = $item['value'];
else $res[$item['source']] += $item['value'];
}
?>
After this, you will have array $res which will be something like:
Array(
[397] => 2,
[1314] => 1
)
Then, if you really need the format specified, you can use something like:
<?
$final = Array();
foreach ($res as $source=>$value) $final[] = Array(
'source' => $source,
'value' => $value
);
?>
This code will do the counting and produce a $new array as described in your example.
$data = array(
array('source' => 397, 'value' => 1),
array('source' => 397, 'value' => 1),
array('source' => 1314, 'value' => 1),
);
$new = array();
foreach ($data as $item)
{
$source = $item['source'];
if (isset($new[$source]))
$new[$source]['value'] += $item['value'];
else
$new[$source] = $item;
}
$new = array_values($new);
PHP has a function called array_count_values for that. May be you can use it
Example:
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
Output:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)

Categories