change the json array order - php

Iam developing an appliacation using CI.I have got a problem and I need a help for that.this is my problem.
I have an array generated with php:
Array
(
[0] => Array
(
[0] => 3
[1] => 0
)
[1] => Array
(
[0] => 2
[1] => 0
)
[2] => Array
(
[0] => 1
[1] => 246
)
[3] => Array
(
[0] => 0
[1] => 4528
)
)
This is the code that genarate above array.
public function get_previous_months_total()
{
$f = 1;
$dataset2 = array();
$result;
for($i=0;$i<4;$i++){
$firstday = mktime(0, 0, 0, date('m')-$f, 1, date('Y'));
$lastday = mktime(0, 0, 0, date('m')-$i, 0, date('Y'));
$end = date("Y-m-d", $lastday);
$start = date("Y-m-d", $firstday);
$f++;
$result = $this->LineChart_Model->get_months_total($start,$end);
foreach ($result as $return_result ){
$dataset2[] = array($i,int)$return_result['SUM(operation_production)']);
}
}
$mon = array(array_reverse($dataset2));
return $mon;
}
Here is the code in the Model.
public function get_months_total($start,$end){
$sql = "SELECT SUM(operation_production) FROM plant WHERE date BETWEEN '".$start."' AND '".$end."' ORDER BY operation_id DESC";
$result = $this->linechart_db->query($sql);
return $result->result_array();
}
after this I encode this using json_encode which gives me the result below:
var total = [
[
3,
0
],
[
2,
0
],
[
1,
246
],
[
0,
4528
]
];
I need to change the order to this:
var total = [
[
0,
0
],
[
1,
0
],
[
2,
246
],
[
3,
4528
]
];
please help me on this. I have tried many ways, but none have worked. any help is really appreciated.

You should be able to use the array_mulisort() function to resolve this issue.
**EDIT:
After further investigation the array_multisort() function will not give you your answer, I apologize.
Since the values of your array are already set, your going to have to manipulate them to get the result you want. Here is what worked for me (in your code just replace the $oldArray variable with the name of your array) :
$replacementArray = array();
$i = 0;
foreach($oldArray as $array) {
$newArray =[$i, $array[1]];
array_push($replacementArray, $newArray);
$i++;
}
$finalArray = array_replace($oldArray, $replacementArray);
$json = json_encode($finalArray);
echo $json;
This will give the following output:
[[0,0],[1,0],[2,246],[3,4528]]

Related

How to check if a multidimensional array key is in an array more than once?

I have this multi array:
Array (
[0] => Array (
[title] => f2
)
[1] => Array (
[title] => f2
)
[2] => Array (
[title] => f3
)
)
I just want to check, if a key (represented by $item) is in the array more than once, so in my case 'f2' is in it more than once.
I tried it using in_array, but it didn't work with multi arrays.
Then I tried this:
$item='f2';
$array_count = array_count_values($titles);
if (array_key_exists($item, $array_count) && ($array_count[$item] > 1))
{
echo 'more than once';
}
but this is still not working.
A combination of array_column and array_count_values can be used:
$arr = [
[
'title' => 'f2'
],
[
'title' => 'f2'
],
[
'title' => 'f3'
]
];
$counts = array_count_values(array_column($arr, 'title'));
print_r($counts);
Output
Array
(
[f2] => 2
[f3] => 1
)
Once you have the total count, you can simply do:
if (($counts[$item] ?? 0) > 1) {
// do action
}
Reading Material
Null coalescing operator
Loop and count, bail if you've already seen your pair:
<?php
$items =
[
['letter'=>'a'],
['letter'=>'a'],
['letter'=>'c']
];
$n = 0; $result = false;
foreach($items as $item) {
if(($item['letter'] ?? null) == 'a' && $n++) {
$result = true;
break;
}
}
var_dump($result);
Output:
bool(true)
You could filter your items and see if the count is greater than 1:
<?php
$items =
[
['letter'=>'a'],
['letter'=>'a'],
['letter'=>'c']
];
var_dump(count(array_filter($items, function($item) {
return ($item['letter'] ?? null) == 'a';
})) > 1);
Output:
bool(true)

How to add multiple array elements into a transposed structure?

I have these arrays
$months = ['jan', 'feb'];
$cashUniform = [2000, 1200];
$cashFee = [24000, 34000];
$cashExpenses = [4000, 300];
Am trying to create an object from these arrays like so:
$data = [{
'month': 'jan',
'cashUniform': 2000,
'cashFee': 24000,
'cashExpenses': 4000,
},
{
'month': 'feb',
'cashUniform': 12000,
'cashFee': 34000,
'cashExpenses': 300,
}
];
I've tried array_combine but it only accepts two array elements, and in my case, I have four array elements.
I've also tried to to create a multiple array.
$data['months'] = $months;
$data['cashFee'] = $cashFee;
$data['cashUniform'] = $cashUniform;
$data['cashExpenses'] = $cashExpenses;
dd(json_encode($data));
The code above returns
{"months":["JAN","FEB"],"cashFee": [12500,2000],"cashUniform":[2000,0],"cashExpenses":[1500,0]}
You can use a simple for loop to loop over all arrays and add the values to a single array:
$data = [];
for ($i = 0; $i < count($months); $i++) {
$data[] = [
'month' => $monts[$i],
'cashUniform' => $cashUniform[$i],
'cashFee' => $cashFee[$i],
'cashExpenses' => $cashExpenses[$i],
];
}
dd($data);
This does require that all arrays have the same amount of values!
$data = [];
foreach ($months as $index => $value) {
$data[] = [
'month' => $monts[$index],
'cashUniform' => $cashUniform[$index],
'cashFee' => $cashFee[$index],
'cashExpenses' => $cashExpenses[$index],
];
}
dd($data);
How about some elegant functional programming so that you don't need to declare a global result array? Transpose the individually declared input data using array_map() -- this synchronously iterates each array. Then name the custom function's parameters to align with the desired keys in the output's subarrays. Use compact() to avoid manually re-writing the keys and variables in the return line.
Code: (Demo)
$months = ['jan', 'feb'];
$cashUniform = [2000, 1200];
$cashFee = [24000, 34000];
$cashExpenses = [4000, 300];
var_export(
array_map(
function ($month, $cashUniform, $cashFee, $cashExpenses) {
return compact(['month', 'cashUniform', 'cashFee', 'cashExpenses']);
},
$months,
$cashUniform,
$cashFee,
$cashExpenses
)
);
Output:
array (
0 =>
array (
'month' => 'jan',
'cashUniform' => 2000,
'cashFee' => 24000,
'cashExpenses' => 4000,
),
1 =>
array (
'month' => 'feb',
'cashUniform' => 1200,
'cashFee' => 34000,
'cashExpenses' => 300,
),
)

Conditional remove adjacent duplicates from array

I have following code that removes adjacent duplicates from the $myArray
<?php
$myArray = array(
0 => 0,
1 => 0,
2 => 1,
5 => 1,
6 => 2,
7 => 2,
8 => 2,
9 => 0,
10 => 0,
);
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem) use (&$previtem) {
$p = $previtem;
$previtem= $currentItem;
return $currentItem!== $p ;
}
);
echo "<pre>";
print_r($newArray);
?>
It works perfectly fine, but I have to change a condition bit for value 2. That means for other values we can pick first occurrence and ignore the others. But for 2, we need to pick last occurrence and ignore others.
So required output is
Array
(
[0] => 0 //first occurrence of 0 in $myArray
[2] => 1 //first occurrence of 1 in $myArray
[8] => 2 //last occurrence of 2 in the $myArray
[9] => 0 //first occurrence of 0 in $myArray
)
How to modify my code to achieve above result??
In reality I have multidimensional array, but for better explanation I have used single dimensional array here in the question.
UPDATE
My actual array is
$myArray = array(
0 => array("Value"=>0, "Tax" => "11.00"),
1 => array("Value"=>0, "Tax" => "12.00"),
2 => array("Value"=>1, "Tax" => "13.00"),
5 => array("Value"=>1, "Tax" => "14.00"),
6 => array("Value"=>2, "Tax" => "15.00"),
7 => array("Value"=>2, "Tax" => "16.00"),
8 => array("Value"=>2, "Tax" => "17.00"),
9 => array("Value"=>0, "Tax" => "18.00"),
10 => array("Value"=>0, "Tax" => "19.00"),
);
And my actual code
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem) use (&$previtem) {
$p["Value"] = $previtem["Value"];
$previtem["Value"] = $currentItem["Value"];
return $currentItem["Value"]!== $p["Value"] ;
}
);
Thanks
This should do what you are looking for.
function array_filter($a) {
$na = array();
$first = true;
$p = null;
$wantlast = false;
foreach ($a as $v) {
if ($wantlast) {
($v != $p) ? $na[] = $p: null;
}
$wantlast = ($v == 2) ? true : false;
if (!$wantlast) {
(($v != $p) || ($first))? $na[] = $v : null;
}
$p = $v;
$first = false;
}
return $na;
}
$myArray = array(
0 => 0,
1 => 0,
2 => 1,
5 => 1,
6 => 2,
7 => 2,
8 => 2,
9 => 0,
10 => 0,
);
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem, $key) use (&$previtem,$myArray) {
$p = $previtem;
if($currentItem != 2){
$previtem = $currentItem;
}else{
$lastkey = array_search(2,(array_reverse($myArray, true)));
if($key != $lastkey)
$currentItem = $previtem;
}
return $currentItem!== $p ;
}, ARRAY_FILTER_USE_BOTH
);
echo "<pre>";
print_r($newArray);

Prepend key value to array - PHP

I have the below code in a for..loop is there a way I can add values to the beginning of the array?
$data = array();
$initial = strtotime('11:00:00');
for (; $initial < strtotime("23:00:59"); $initial = strtotime("+15 minutes", $initial)) {
if ($initial > strtotime("+45 minutes", time())) {
$row['value'] = date('Hi', $initial);
$row['label'] = date('H:i', $initial);
$data['data'][] = $row;
}
}
I want to add the below values to the top of the array. I have tried using array_unshift but I don't think it supports key-value pairs.
if(!isBetween('22:00', '09:59', date('H:i'))) {
$row['value'] = "asap";
$row['label'] = "ASAP";
}
My array output
{
"data": [
{
"value": "1145",
"label": "11:45"
}
]
}
I want to get this
{
"data": [
{
"value": "asap",
"label": "ASAP"
},{
"value": "1145",
"label": "11:45"
},
]
}
Un-shift should work if you pass the arguments correctly:
array_unshift($data["data"], $prepend);
Alternatively, you could use array_merge, like this:
$data["data"] = array_merge(array($prepend), $data["data"]);
With the following example data:
$data = [
"data" => [
[
"value" => "1145",
"label" => "11:45"
]
]
];
$prepend = [
"value" => "asap",
"label" => "ASAP"
];
$data["data"] = array_merge(array($prepend), $data["data"]);
print_r($data);
You would get this output (with both solutions):
Array (
[data] => Array (
[0] => Array (
[value] => asap
[label] => ASAP
)
[1] => Array (
[value] => 1145
[label] => 11:45
)
)
)
If you need to prepend something to the array without the keys being reindexed and/or need to prepend a key value pair, you can use this short function:
function array_unshift_assoc(&$arr, $key, $val) {
$arr = array_reverse($arr, true);
$arr[$key] = $val;
return array_reverse($arr, true);
}
Source: http://php.net/manual/en/function.array-unshift.php

Sum values in array and simplify key names

This is almost similar to my other question which is related to the same project I'm working on.. Link to my other question
but in this case the array is different as follow:
Array
(
[2014-08-01 11:27:03] => 2
[2014-08-01 11:52:57] => 2
[2014-08-01 11:54:49] => 2
[2014-08-02 11:59:54] => 4
[2014-08-02 12:02:41] => 2
[2014-08-05 12:09:38] => 4
[2014-08-07 12:23:12] => 3
[2014-08-07 12:25:18] => 3
// and so on...
)
That is my output array and in order to get that array I had to do some miracles... anyway, so based on that array I have to sum the value for each key date and build an array something like this...
Array
(
[2014-08-01] => 6
[2014-08-02] => 6
[2014-08-05] => 4
[2014-08-07] => 6
// and so on...
)
That last array will be use to build graphs with morrisonJS, what I have is this:
$res_meno = array();
foreach ($sunArr as $keys => $values) {
$arrays= explode(" ",$sumArr[$keys]);
$res_meno[] = $arrays[0];
}
$vals_char2 = array_count_values($res_meno);
That is my attempt to build my last array but is not working...
any help would be greatly appreciated!
Thank you for taking the time.
Try this code
<?php
$arr = array(
"2014-08-01 11:27:03" => 2,
"2014-08-01 11:52:57" => 2,
"2014-08-01 11:54:49" => 2,
"2014-08-02 11:59:54" => 4,
"2014-08-02 12:02:41" => 2,
"2014-08-05 12:09:38" => 4,
"2014-08-07 12:23:12" => 3,
"2014-08-07 12:25:18" => 3
);
$new_array = array();
foreach($arr as $k => $v){
$date = reset(explode(" ", $k));
if(isset($new_array[$date])){
$new_array[$date] += $v;
}
else{
$new_array[$date] = $v;
}
}
print_r($new_array);
?>
DEMO
$sunArr = array
(
"2014-08-01 11:27:03" => 2,
"2014-08-01 11:52:57" => 2,
"2014-08-01 11:54:49" => 2,
"2014-08-02 11:59:54" => 4,
"2014-08-02 12:02:41" => 2,
"2014-08-05 12:09:38" => 4,
"2014-08-07 12:23:12" => 3,
"2014-08-07 12:25:18" => 3,
);
$res_meno = array();
foreach ($sunArr as $keys => $values) {
$arrays= explode(" ",$keys);
if(isset($res_meno[$arrays[0]]))
{
$res_meno[$arrays[0]] = $res_meno[$arrays[0]] + $values;
}
else
{
$res_meno[$arrays[0]] = $values;
}
}
print_r($res_meno);
exit;
Try this, i think it might fix the problem
Try this PHP Code You Can test here
$sunArr = Array
(
'2014-08-01 11:27:03' => 2,
'2014-08-01 11:52:57' => 2,
'2014-08-01 11:54:49' => 2,
'2014-08-02 11:59:54' => 4,
'2014-08-02 12:02:41' => 2,
'2014-08-05 12:09:3' => 4,
'2014-08-07 12:23:12' => 3,
'2014-08-07 12:25:18' => 3
);
$key = 0;
$res_meno = array();
foreach ($sunArr as $keys => $values)
{
$ar= explode(" ", $keys);
if( $key == $ar[0] )
{
$res_meno[$key] = $sunArr[$keys] + $res_meno[$key];
}
else
{
$key = $ar[0];
$res_meno[$key] = $values;
}
}
echo '<pre>';
print_r($res_meno);
die;
Where does the first array come from? If it's from a SQL database, it's better to create a query that returns the aggregated array.
Otherwise no need to use array_key_values for that:
$res_meno = array();
foreach ($sumArr as $keys => $values) {
$key = substr($keys, 0, 10);
$res_meno[$key] = (empty($res_meno[$key]) ? 0 : $res_meno[$key]) + $values;
}
Here is a solution which uses a callback. Not to use loops is often better!
$sunArr = array(
'2014-08-01 11:27:03' => 3,
'2014-08-01 11:27:05' => 5,
'2013-09-01 11:01:05' => 1
);
$res = array();
function map($item, $key, &$result)
{
$result[current(explode(" ", $key))] += $item;
}
array_walk($sunArr, "map", &$res);
var_dump($res);
You can test it here on codepad.

Categories