how to count length of arrays created dynamically? - php

I have an array
dump($data);
*************************************
array(10) {
["12-male"] => string(1) "2"
["11-male"] => string(1) "2"
["10-female"] => string(1) "2"
["16-female"] => string(1) "2"
["9-male"] => string(1) "2"
["17-male"] => string(1) "4"
["14-male"] => string(1) "4"
["15-female"] => string(1) "4"
["13-female"] => string(1) "5"
["18-female"] => string(1) "6"
}
******************************************
I am DYNAMICALLY getting like sub arrays out of the array above
$rooms = array();
foreach ($data as $key => $value) {
$rooms['room'.$value][] = $key;
$rooms['room'.$value]['count'] = sizeof($rooms['room'.$value]);
}
dump($rooms);
******************************************
I get this result
Dump => array(4) {
["room2"] => array(6) { //array size=6
[0] => string(7) "12-male"
["count"] => int(6) //count of array size=6
[1] => string(7) "11-male"
[2] => string(9) "10-female"
[3] => string(9) "16-female"
[4] => string(6) "9-male"
}
["room4"] => array(4) { //array size=4
[0] => string(7) "17-male"
["count"] => int(4) //count of array size=4
[1] => string(7) "14-male"
[2] => string(9) "15-female"
}
["room5"] => array(2) { //array size=2
[0] => string(9) "13-female"
["count"] => int(1) //count of array size=1 (the problem here)
}
["room6"] => array(2) { //array size=2
[0] => string(9) "18-female"
["count"] => int(1) //count of array size=1 (the problem here)
}
}
My issue is that, the count is returned correctly after first 2 iterations, after that the count is always showing 1, no matter the size of array.
I tried count() as well but the result is the same.

You could do like below:
$rooms = array();
foreach ($data as $key => $value) {
if (!isset($rooms['room'.$value])) {
$rooms['room'.$value] = array('count' => 0);
}
$rooms['room'.$value][] = $key;
$rooms['room'.$value]['count']++;
}
But you don't need to add the count into your array.

The reason the count is doing that is that from room2 and room4 you are inserting 'count' on the first iteration, then on subsequent iterations 'count' is included in the sizeof() request. For room 5 and room6 as they are iterated only once sizeof() is only called once, before 'count' is inserted into the array, so it's not the index of 'count' not included in the result of sizeof for those items.

Related

PHP - How to combine two arrays with different number of elements?

I have two arrays:
One:
array(4) {
[0]=> array(2) {
[0]=> string(19) "Ford"
[1]=> string(1) "1"
}
[1]=> array(2) {
[0]=> string(15) "Chevrolet"
[1]=> string(1) "1"
}
[2]=> array(2) {
[0]=> string(7) "VW"
[1]=> string(1) "1"
}
[3]=> array(2) {
[0]=> string(4) "Fiat"
[1]=> string(1) "3"
}
}
Two:
array(6) {
[0]=> string(7) "#581845"
[1]=> string(7) "#900C3F"
[2]=> string(7) "#C70039"
[3]=> string(7) "#FF5733"
[4]=> string(7) "#FFC300"
[5]=> string(7) "#DAF7A6"
}
Now, I need the first array combining with the second, excluding the elements of the second array that are not used by the first. At the end, I want to receive an array like:
[0]=> {
[0]=> "Ford",
[1]=> "1",
[2]=>"#581845"
}
[1]=>
...
}
Provided you always have more colors than auto makes, you can do this:
$makes = [
[
"Ford",
"1"
],
[
"Chevrolet",
"1"
],
[
"VW",
"1"
],
[
"Fiat",
"3"
]
];
$colors = [
"#581845",
"#900C3F",
"#C70039",
"#FF5733",
"#FFC300",
"#DAF7A6"
];
foreach($makes as &$currMakeTuple)
{
$currMakeTuple[] = array_shift($colors);
}
print_r($makes);
Array
(
[0] => Array
(
[0] => Ford
[1] => 1
[2] => #581845
)
[1] => Array
(
[0] => Chevrolet
[1] => 1
[2] => #900C3F
)
[2] => Array
(
[0] => VW
[1] => 1
[2] => #C70039
)
[3] => Array
(
[0] => Fiat
[1] => 3
[2] => #FF5733
)
)
You should probably check that condition and have a contingency for it.
Another one solution. Independent of the number of colors. Will add to brands only those colors which keys are equal to the brands' keys.
$brands = [
['Ford', 1],
['Chevrolet', 1],
['VW', 1],
['Fiat', 3],
];
$colors = [
'#581845',
'#900C3F',
'#C70039',
'#FF5733',
'#FFC300',
'#DAF7A6',
];
array_walk($brands, function(&$value, $key, $colors) {
if (isset($colors[$key])) {
$value = array_merge($value, [$colors[$key]]);
}
}, $colors);
print_r($brands);
I'm not saying you should do it this way, but I thought it was worth showing an alternative that used array functions instead:
var_dump(array_map(function($make, $color) {
$make[] = $color;
return $make;
}, $makes, array_slice($colors, 0, count($makes))));
I used:
array_slice to reduce the $colors array, should it be too long.
array_map with a lambda (anonymous function) that will apply the lambda to each element and return the final array upon completion.

nested array into simple nested array in php

I have an array
[0] => array(3) {
["id"] => string(1) "2"
["name"] => string(10) "Contractor"
["statuses"] => array(4) {
[1] => array(3) {
["id"] => string(1) "1"
["name"] => string(3) "NEW"
["count"] => string(2) "32"
}
[3] => array(3) {
["id"] => string(1) "3"
["name"] => string(8) "RETURNED"
["count"] => string(2) "20"
}
[5] => array(3) {
["id"] => string(1) "5"
["name"] => string(6) "FAILED"
["count"] => string(2) "46"
}
[58] => array(3) {
["id"] => string(2) "58"
["name"] => string(6) "REVISE"
["count"] => string(3) "197"
}
}
}
now when I convert into JSON it look like this
"items":[{"id":"2","name":"Contractor","statuses":{"1":{"id":"1","name":"NEW","count":"32"},"3":{"id":"3","name":"RETURNED","count":"20"},"5":{"id":"5","name":"FAILED","count":"46"},"58":{"id":"58","name":"REVISE","count":"197"}}}...
how to I remove the preceding 1, 3, 6 and 58 from array or JSON
I have tried array_values() but it is not converting the nested part of the array
how to i remove the preceding 1, 3, 6 and 58 from array or json
If you want json_encode() to return JSON array all the array keys must:
be numeric
be in sequence
the sequence must start from 0
For example:
$a = [1,2,3];
echo json_encode($a);
outputs desired
[1,2,3]
same with explicitly set indexes:
$a = [0=>1,2,3];
but
$a = [1=>1,2,3];
would output object:
{"1":1,"2":2,"3":3}
because sequence does not start from 0. Same for your case:
$a = [1,2,58=>3];
which produces
{"0":1,"1":2,"58":3}
because continuity of the key sequence is broken by index 58.
So depending on how you build your source array simply remove own keys with i.e. array_values():
$a = [1,2,58=>3];
echo json_encode(array_values($a)]);
would produce
[1,2,3]
so use array_values() on your $data['statuses'] and you are done.

Displaying Array Values from DB

I can`t find a way to loop this structure of array . Anyone does encounter it.?
Print_r output
Array (
[0] => Array ( [0] => [LABOR_NO] => [1] => 3 [WORK_CODE] => 3 [2] => [MHR] => [3] => [PHR] => [4] => [PESO_VALUE] => )
[1] => Array ( [0] => [LABOR_NO] => [1] => 3 [WORK_CODE] => 3 [2] => [MHR] => [3] => [PHR] => [4] => [PESO_VALUE] => )
[2] => Array ( [0] => 1 [LABOR_NO] => 1 [1] => 3 [WORK_CODE] => 3 [2] => 2.50 [MHR] => 2.50 [3] => 0.00 [PHR] => 0.00 [4] => 3000.00 [PESO_VALUE] => 3000.00 )
)
Vardump Output
array(3) {
[0]=> array(10) {
[0]=> NULL ["LABOR_NO"]=> NULL [1]=> string(1) "3" ["WORK_CODE"]=> string(1) "3" [2]=> NULL ["MHR"]=> NULL [3]=> NULL ["PHR"]=> NULL [4]=> NULL ["PESO_VALUE"]=> NULL }
[1]=> array(10) { [0]=> NULL ["LABOR_NO"]=> NULL [1]=> string(1) "3" ["WORK_CODE"]=> string(1) "3" [2]=> NULL ["MHR"]=> NULL [3]=> NULL ["PHR"]=> NULL [4]=> NULL ["PESO_VALUE"]=> NULL }
[2]=> array(10) { [0]=> string(1) "1" ["LABOR_NO"]=> string(1) "1" [1]=> string(1) "3" ["WORK_CODE"]=> string(1) "3" [2]=> string(4) "2.50" ["MHR"]=> string(4) "2.50" [3]=> string(4) "0.00" ["PHR"]=> string(4) "0.00" [4]=> string(7) "3000.00" ["PESO_VALUE"]=> string(7) "3000.00" }
}
Heres what i have done but not working i think. i dont know => has been continues to each that turned them to $keys..
include('MySQLHandler.php');
class Displayer extends MySQLHandler {
public function getTitle($batchNo = NULL,$workCode = NULL){
$this->init();
$STMT="SELECT REC_NO,PARTS_WORKSCOPE FROM RAPID_TEMP_ESTIMATE_V3 WHERE BATCH_NO={$batchNo} AND WORK_CODE={$workCode} AND PARTS_WORKSCOPE_TYPE='Workscope:'";
$DATA=$this->Select($STMT);
// create array of data subjects..
$result = array();
$result['REC_NO'] = $DATA[0]['REC_NO'];
$result['PARTS_WORKSCOPE'] = $DATA[0]['PARTS_WORKSCOPE'];
return $result;
}
public function getTotal($batchNo = NULL,$workCode = NULL){
$this->init();
// par selection
$STMT="SELECT PAR_VALUE FROM RAPID_PAR WHERE PAR_NAME='LABOR_RATE_PER_HOUR'";
$DATA = $this->Select($STMT);
$PAR_VALUE = $DATA[0]['PAR_VALUE'];
// rollup
$STMT="SELECT LABOR_NO,WORK_CODE,MHR,PHR,PESO_VALUE FROM RAPID_TEMP_ESTIMATE_V3 WHERE BATCH_NO={$batchNo} AND WORK_CODE={$workCode} ORDER BY MINOR_WORK_CODE, WORK_CODE_ORDER";
$DATA=$this->Select($STMT);
foreach($DATA as $key=>$value){
foreach($value as $fieldset=>$values){
echo $fieldset.'<br/>';
}
}
}
}
$displayer = new Displayer;
$displayer->getTotal(18,3);

php switch array key with subelement key

I would like to switch the main keys(0,1,2) of an array with a subelement key(user_id).
For example, from this array:
array(3) {
[0]=>
array(3) {
["num_products_user_by_ref"]=>
string(1) "1"
["user_id"]=>
string(2) "77"
["reference"]=>
string(3) "E49"
}
[1]=>
array(3) {
["num_products_user_by_ref"]=>
string(1) "9"
["user_id"]=>
string(3) "526"
["reference"]=>
string(3) "E49"
}
[2]=>
array(3) {
["num_products_user_by_ref"]=>
string(2) "38"
["user_id"]=>
string(3) "346"
["reference"]=>
string(3) "E49"
}
}
I need :
array(952) {
[77]=>
array(2) {
["num_products_user_by_ref"]=>
string(1) "1"
["reference"]=>
string(3) "E49"
}
[526]=>
array(3) {
["num_products_user_by_ref"]=>
string(1) "9"
["reference"]=>
string(3) "E49"
}
[346]=>
array(3) {
["num_products_user_by_ref"]=>
string(2) "38"
["reference"]=>
string(3) "E49"
}
Every user_id could contains more than 1 pair num_products_user_by_ref/reference.
I remember that there is a function to achieve this (ksort?) associated to a custom function to implement.
$out = array();
foreach ($arr as $key => $value){
$out[$value['user_id']]["num_products_user_by_ref"] = $value["num_products_user_by_ref"];
$out[$value['user_id']]["reference"] = $value["reference"];
}
print_r($out);
Your question showed a structure that doesn't seem to fit with your comment "Every user_id could contains more than 1 pair num_products_user_by_ref/reference." So, here's another version that allows for that possibility:
$out = array();
foreach ($arr as $key => $value){
$entry = array("num_products_user_by_ref" => $value["num_products_user_by_ref"],
"reference" => $value["reference"]);
$out[$value['user_id']][] = $entry;
}
Output:
Array
(
[77] => Array
(
[0] => Array
(
[num_products_user_by_ref] => 1
[reference] => E49
)
[1] => Array
(
[num_products_user_by_ref] => 5
[reference] => E49
)
)
[526] => Array
(
[0] => Array
(
[num_products_user_by_ref] => 9
[reference] => E49
)
)
[346] => Array
(
[0] => Array
(
[num_products_user_by_ref] => 38
[reference] => E49
)
)
)
Here's another version for those who don't like traditional loops:
$out = array();
array_walk($arr, function($e, $k) use(&$out){
$entry = array("num_products_user_by_ref" => $e["num_products_user_by_ref"],
"reference" => $e["reference"]);
$out[$e['user_id']][] = $entry;
});

Confusion with multidimensional arrays and merging

I have had success merging two arrays by difference using the following code:
$a=array("2013-08-22"=>"12","2013-08-25"=>"5","2013-08-27"=>"10");
$b=array("2013-08-22"=>"1","2013-08-23"=>"3","2013-08-25"=>"5","2013-08-27"=>"10","2013-08-29"=>"5");
foreach ($b as $key => $value){
if(!array_key_exists($key, $a)){
$a[$key]=0;
}
}
This will return:
Array
(
[2013-08-22] => 0
[2013-08-23] => 0
[2013-08-25] => 5
[2013-08-27] => 10
[2013-08-29] => 0
[2013-12-22] => 12
)
The idea is for a to additionally hold the elements from b that are not present in a.
I am having issues now doing the same thing for the following array format:
$a=array(array("2013-12-22","12"),array("2013-08-25","5"),array("2013-08-27","10"));
$b=array(array("2013-08-22","1"),array("2013-08-23","3"),array("2013-08-25","5"),array("2013-08-27","10"),array("2013-08-29","5"));
I went to try this:
foreach ($b as $key => $value){
if(!array_key_exists($key, $a)){
$a[$key]=array($value[0], 0);
}
}
But the returned result is far from what I need:
Array
(
[0] => Array
(
[0] => 2013-12-22
[1] => 12
)
[1] => Array
(
[0] => 2013-08-25
[1] => 5
)
[2] => Array
(
[0] => 2013-08-27
[1] => 10
)
[3] => Array
(
[0] => 2013-08-27
[1] => 0
)
[4] => Array
(
[0] => 2013-08-29
[1] => 0
)
)
I understand they keys are no longer the dates, but how should I go about checking each array and making sure I don't get double entries?
$a = array(
array("2013-12-22","12"),
array("2013-08-25","5"),
array("2013-08-27","10"));
$b = array(
array("2013-08-22","1"),
array("2013-08-23","3"),
array("2013-08-25","5"),
array("2013-08-27","10"),
array("2013-08-29","5"));
$exists = array();
foreach ($a as $data) {
$exists[$data[0]] = 1;
}
foreach ($b as $data) {
if (array_key_exists($data[0], $exists)) {
continue;
}
$a[] = array($data[0], $data[1]);
}
$a now contains:
array(6) {
[0]=>
array(2) {
[0]=>
string(10) "2013-12-22"
[1]=>
string(2) "12"
}
[1]=>
array(2) {
[0]=>
string(10) "2013-08-25"
[1]=>
string(1) "5"
}
[2]=>
array(2) {
[0]=>
string(10) "2013-08-27"
[1]=>
string(2) "10"
}
[3]=>
array(2) {
[0]=>
string(10) "2013-08-22"
[1]=>
string(1) "1"
}
[4]=>
array(2) {
[0]=>
string(10) "2013-08-23"
[1]=>
string(1) "3"
}
[5]=>
array(2) {
[0]=>
string(10) "2013-08-29"
[1]=>
string(1) "5"
}
}

Categories