add elements of associative array with same key - php

I have associative array like this
$min_stats=
array(2)
{
[0]=> array(3)
{
["minute"]=> object(MongoInt64)#13 (1)
{
["value"]=> string(8) "10"
}
["add"]=> object(MongoInt64)#14 (1)
{
["value"]=> string(1) "9"
}
["tag"]=> object(MongoInt64)#15 (1)
{
["value"]=> string(1) "4"
}
}
[1]=> array(3)
{
["minute"]=> object(MongoInt64)#13 (1)
{
["value"]=> string(8) "11"
}
["add"]=> object(MongoInt64)#14 (1)
{
["value"]=> string(1) "9"
}
["tag"]=> object(MongoInt64)#15 (1)
{
["value"]=> string(1) "5"
}
}
} Array
Now I want to combine all the key-value pair in the array to get one array.
The resulting array should be
array(11)
{
["minute"]=> int(21)
["add"]=> int(18)
["tag"]=> int(9)
} Array
so for what I have written is
foreach ($min_stats as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
$sumArray[$id]+=$value;
}
}
but its not giving me correct results, I don't know what I'm doing wrong?
The $value is coming as 2 means its just counting the elements in the subarray.
Thanks in advance for the help.

You can do it like this:
$finalArr = array();
foreach($array as $k1 => $v1){
foreach($v1 as $k2=>$v2){
if(!isset($finalArr[$k2])){
$finalArr[$k2] = 0;
}
$finalArr[$k2] += $v2['value'];
}
}
print_r($finalArr);
Output:
Array
(
[minute] => 21
[add] => 18
[tag] => 9
)
Easy copy array for testing:
$array = array(
array(
'minute' => array(
'value' => '10'
),
'add' => array(
'value' => '9'
),
'tag' => array(
'value' => '4'
),
),
array(
'minute' => array(
'value' => '11'
),
'add' => array(
'value' => '9'
),
'tag' => array(
'value' => '5'
),
)
);

Related

Merge two different array data in one array php

I want to merge two different array data in one array, but i'm confuse how to use array_push in this case.
this is example of my data input:
["author"]=>
array(2) {
[0]=>
string(1) "John"
[1]=>
string(1) "Doe"
}
["title"]=>
array(2) {
[0]=>
string(1) "book a"
[1]=>
string(1) "book b"
}
And the result in one array that i mean, like this:
["books"]=>
array(2) {
[0] =>
array(2) {
["author"]=>
string(1) "John"
["title"]=>
string(1) "book a"
}
[1] =>
array(2) {
["author"]=>
string(1) "Doe"
["title"]=>
string(1) "book b"
}
}
I already try using this way but it just return 1 from each array:
$data['books'] = [];
array_push($data['books'], [
'author' => $data['author'],
'title' => $data['title']
]);
if (isset($data['books'])) {
foreach ($data['books'] as $k => $v) {
$data['books'][$k]['author'] = (int)$v['author'];
$data['books'][$k]['title'] = (int)$v['title'];
}
}
result:
["books"]=>
array(1) {
[0]=>
array(2) {
["author"]=>
int(1)
["title"]=>
int(1)
}
}
You have to transpose your arrays with the keys in mind.
function transpose(array $arr){
$transArr = [];
foreach($arr as $keyRow => $subArr) {
foreach($subArr as $keyCol => $value) {
$transArr[$keyCol][$keyRow] = $value;
}
}
return $transArr;
}
This function can be used universally for similar problems. The function comes from this class.
How to use:
$input = [
"author"=> ["John","Doe"],
"title" => ["book a","book b"],
];
$books = transpose($input);
echo '<pre>';
var_export($books);
Or if you want to use the class:
$books = tableArray::create($input)
->transpose()
->fetchAll()
;
Output:
array (
0 =>
array (
'author' => 'John',
'title' => 'book a',
),
1 =>
array (
'author' => 'Doe',
'title' => 'book b',
),
)
If "author" and "title" exist as two arrays, $ input must first be created like this:
$input = ['author' => $arrayAuthor, 'title' => $arrayTitle];

Merging keys in a multidimensional array

I have this multidimensional array:
array(3) {
[0]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(2)
}
[1]=>
array(2) {
["casestatus"]=> string(7) "Pending"
["casestatus_count"]=> int(1)
}
[2]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(1)
}
}
From the array above I am able to merge based on the casestatus key as shown below:
$newArray = array();
foreach($mergedData as $data)
{
if(!isset($newArray[$data["casestatus"]]))
{
$newArray[$data["casestatus"]] = array(
"casestatus" => $data["casestatus"],
"casestatus_count" => 0
);
}
$newArray[$data["casestatus"]]["casestatus_count"] += $data["casestatus_count"];
}
var_dump($newArray);
From which I get:
array(2) {
["Open"]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(3)
}
["Pending"]=>
array(2) {
["casestatus"]=> string(7) "Pending"
["casestatus_count"]=> int(1)
}
}
Note how my array keys are my casestatus. So is there a way of not having this and instead have my array keys as:
array(2) {
[0]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(3)
}
[1]=>
array(2) {
["casestatus"]=> string(7) "Pending"
["casestatus_count"]=> int(1)
}
}
Just do array_values($newArray) after the process.
var_dump(array_values($newArray));
array_values()
You could create a map of status to counts, then sum them:
<?php
$tickets =
[
[
'status' => 'Open',
'count' => 2
],
[
'status' => 'Closed',
'count' => 1
],
[
'status' => 'Open',
'count' => 1
]
];
foreach($tickets as $ticket)
$status_counts[$ticket['status']][] = $ticket['count'];
foreach($status_counts as $status => $counts)
$result[] = [
'status' => $status,
'count' => array_sum($counts)
];
var_export($result);
Output:
array (
0 =>
array (
'status' => 'Open',
'count' => 3,
),
1 =>
array (
'status' => 'Closed',
'count' => 1,
),
)
However a simpler format may suffice:
$result = array_map('array_sum', $status_counts);
var_export($result);
Output:
array (
'Open' => 3,
'Closed' => 1,
)

PHP how to remove duplicate or equal array value and append the data in an array

I have an array with 4 data each, what i want to accomplish is to remove
value of duplicate/equal tag_id and put/append the tag_images together
of the same tag_id. I also used array_unique but i don't know where to put it.
My array has a tag_id,tag_slug,tag_color, and tag_images(array). The last 2 array have the same data except with tag_images, I want to merge those data as one and put the tag_images in an array.
example:
array(4) {
[0]=>
array(4) {
["tag_id"]=> int(25)
["tag_slug"]=> string(5) "green"
["tag_color"]=> string(7) "#81d742"
["tag_images"]=> array(1) {
[0]=> string(75) "http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg"
}
}
[1]=>
array(4) {
["tag_id"]=> int(23)
["tag_slug"]=> string(3) "red"
["tag_color"]=> string(7) "#dd3333"
["tag_images"]=> array(1) {
[0]=> string(69) "http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg"
}
}
[2]=>
array(4) {
["tag_id"]=> int(23)
["tag_slug"]=> string(3) "red"
["tag_color"]=> string(7) "#dd3333"
["tag_images"]=> array(1) {
[0]=> string(66) "http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg"
}
}
}
Output:
array(4) {
[0]=>
array(4) {
["tag_id"]=>
int(25)
["tag_slug"]=>
string(5) "green"
["tag_color"]=>
string(7) "#81d742"
["tag_images"]=>
array(1) {
[0]=>
string(75) "http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg"
}
}
[1]=>
array(4) {
["tag_id"]=>
int(23)
["tag_slug"]=>
string(3) "red"
["tag_color"]=>
string(7) "#dd3333"
["tag_images"]=>
array(1) {
[0]=>
string(66) "http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg"
[1]=>
string(69) "http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg"
}
}
}
You can use array_merge_recursive()
Or use this function from this answer
function my_array_merge(&$array1, &$array2) {
$result = Array();
foreach($array1 as $key => &$value) {
$result[$key] = array_merge($value, $array2[$key]);
}
return $result;
}
$array = my_array_merge($array1, array2);
print_r($array);
I'd iterate the main array and build a second one.
$mainArray = array
(
array("tag_id" => 25,
"tag_slug" => "green",
"tag_color" => "#81d742",
"tag_images" => array("http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg")
),
array("tag_id" => 23,
"tag_slug" => "red",
"tag_color" => "#dd3333",
"tag_images" => array("http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg")
),
array("tag_id" => 23,
"tag_slug" => "red",
"tag_color" => "#dd3333",
"tag_images" => array("http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg")
)
);
$freshArray = array();
foreach ($mainArray as $value)
{
$key = array_search($value['tag_id'], array_column($freshArray, 'tag_id'));
if (false === $key)
$freshArray[] = $value;
else
$freshArray[$key]['tag_images'][] = $value['tag_images'][0];
}
var_dump($freshArray);
Output :
array (size=2)
0 =>
array (size=4)
'tag_id' => int 25
'tag_slug' => string 'green' (length=5)
'tag_color' => string '#81d742' (length=7)
'tag_images' =>
array (size=1)
0 => string 'http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg' (length=70)
1 =>
array (size=4)
'tag_id' => int 23
'tag_slug' => string 'red' (length=3)
'tag_color' => string '#dd3333' (length=7)
'tag_images' =>
array (size=2)
0 => string 'http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg' (length=64)
1 => string 'http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg' (length=61)

PHP: Generate JSON from array in a specific way

I would like to create a JSON from Array in a specific way. My array looks like this at the beginning:
array(2) {
[22]=>
array(8) {
["factor"]=>
array(2) {
[0]=>
string(2) "12"
[1]=>
string(1) "1"
}
["unit"]=>
array(2) {
[0]=>
string(6) "months"
[1]=>
string(5) "times"
}
["value"]=>
array(2) {
[0]=>
string(3) "2.5"
[1]=>
string(1) "2"
}
["planid"]=>
array(2) {
[0]=>
string(1) "1"
[1]=>
string(1) "1"
}
["position"]=>
array(2) {
[0]=>
string(22) "Test 1"
[1]=>
string(21) "Test 2"
}
["vouchervalue"]=>
array(2) {
[0]=>
string(1) "0"
[1]=>
string(1) "0"
}
["vouchertype"]=>
array(2) {
[0]=>
string(0) ""
[1]=>
string(0) ""
}
["vat"]=>
array(2) {
[0]=>
int(19)
[1]=>
int(19)
}
}
[23]=>
array(8) {
["factor"]=>
array(2) {
[0]=>
string(2) "12"
[1]=>
string(1) "1"
}
["unit"]=>
array(2) {
[0]=>
string(6) "months"
[1]=>
string(5) "times"
}
["value"]=>
array(2) {
[0]=>
string(3) "2.5"
[1]=>
string(1) "2"
}
["planid"]=>
array(2) {
[0]=>
string(1) "1"
[1]=>
string(1) "1"
}
["position"]=>
array(2) {
[0]=>
string(22) "Test 3"
[1]=>
string(21) "Test 4"
}
["vouchervalue"]=>
array(2) {
[0]=>
string(1) "0"
[1]=>
string(1) "0"
}
["vouchertype"]=>
array(2) {
[0]=>
string(0) ""
[1]=>
string(0) ""
}
["vat"]=>
array(2) {
[0]=>
int(19)
[1]=>
int(19)
}
}
}
This is how the JSON looks like:
string(354) "{"factor":[["12","1"],["12","1"]],"unit":[["months","times"],["months","times"]],"value":[["2.5","2"],["2.5","2"]],"planid":[["1","1"],["1","1"]],"position":[["Test 1","Test 2"],["Test 3","Test 4"]],"vouchervalue":[["0","0"],["0","0"]],"vouchertype":[["",""],["",""]],"vat":[[19,19],[19,19]]}"
But I would like to have it this way:
string(214) "{"factor":["12", "1","12","1"],"unit":["months", "times","months","times"],"value":["2.5","2","2.5", "2"],"planid":["1","1","1","1"],"position":["Test 1","Test 2", "Test 3", "Test 4"],"vouchervalue":["0","0","0","0"],"vouchertype":["","","",""],"vat":[19,19,19,19]}"
The idea is that every order can contain more than 1 position that can be used to create a JSON which can be used in the rest of the application (there is a table that uses JSON).
Well, I've no idea how to solve this so I'm happy about any hint :-)
Let us say you have the data in array $a.
$a = array(
array(
'factor'=> array( '12', '1' ),
'unit'=> array( 'months', 'times' ),
'value'=> array( '2.5', '2' ),
'planid'=> array( '1', '1' ),
'position'=> array( 'Test 1', 'Test 2' ),
'vouchervalue'=> array( '0', '0' ),
'vouchertype'=> array( '', '' ),
'vat'=> array( 19, 19 ),
),
array(
'factor'=> array( '12', '1' ),
'unit'=> array( 'months', 'times' ),
'value'=> array( '2.5', '2' ),
'planid'=> array( '1', '1' ),
'position'=> array( 'Test 3', 'Test 4' ),
'vouchervalue'=> array( '0', '0' ),
'vouchertype'=> array( '', '' ),
'vat'=> array( 19, 19),
),
);
This in your example contains two arrays, you want to combine. This is one way:
$b = array();
foreach( $a[0] as $k=>$v ) {
if ( isset( $a[1][$k] ) ) // Add keys in both arrays
$b[$k] = array_merge( $a[0][$k], $a[1][$k] );
else // Add keys in only first array
$b[$k] = $a[0][$k];
}
foreach( $a[1] as $k=>$v ) {
if ( !isset( $a[0][$k] ) ) // Add keys in only second array
$b[$k] = $a[1][$k];
}
echo json_encode( $b );
This iterates through the first array. If the key ('factor', 'unit') is available in both arrays, it merges them otherwise it just adds the array.
Secondly it iterates through the second array and adds the arrays which has not been added in the first pass (if the key was not in the first array).
In your case, the arrays seem to have the same set of keys, and a second pass might not be necessary, but just to be sure...
This is the result:
{"factor":["12","1","12","1"],"unit":["months","times","months","times"],"value":["2.5","2","2.5","2"],"planid":["1","1","1","1"],"position":["Test 1","Test 2","Test 3","Test 4"],"vouchervalue":["0","0","0","0"],"vouchertype":["","","",""],"vat":[19,19,19,19]}
If you do not want the numbers in the json to be string encoded, like "12" but rather 12, add JSON_NUMERIC_CHECK to json_encode
echo json_encode( $b, JSON_NUMERIC_CHECK );
{"factor":[12,1,12,1],"unit":["months","times","months","times"],"value":[2.5,2,2.5,2],"planid":[1,1,1,1],"position":["Test 1","Test 2","Test 3","Test 4"],"vouchervalue":[0,0,0,0],"vouchertype":["","","",""],"vat":[19,19,19,19]}
You're looking for array_merge_recursive(). Per the docs:
array_merge_recursive() merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.
If the input arrays have the same string keys, then the values for these keys are merged together into an array, and this is done recursively, so that if one of the values is an array itself, the function will merge it with a corresponding entry in another array too. If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended.
Using the example inputs that #HasseBjork outlined above in his answer (based on your original input):
$a = array(
array(
'factor'=> array( '12', '1' ),
'unit'=> array( 'months', 'times' ),
'value'=> array( '2.5', '2' ),
'planid'=> array( '1', '1' ),
'position'=> array( 'Test 1', 'Test 2' ),
'vouchervalue'=> array( '0', '0' ),
'vouchertype'=> array( '', '' ),
'vat'=> array( 19, 19 ),
),
array(
'factor'=> array( '12', '1' ),
'unit'=> array( 'months', 'times' ),
'value'=> array( '2.5', '2' ),
'planid'=> array( '1', '1' ),
'position'=> array( 'Test 3', 'Test 4' ),
'vouchervalue'=> array( '0', '0' ),
'vouchertype'=> array( '', '' ),
'vat'=> array( 19, 19),
),
);
All you need to do is:
echo json_encode(array_merge_recursive($a[0], $a[1]));

Searching Multi-Dimension Array With Multiple Results

Let's say I have an array and I want to search for a value should return multiple results:
array(2) {
[0] => array(2) {
["id"] => string(2) "1"
["custom"] => string(1) "2"
}
[1] => array(2) {
["id"] => string(2) "2"
["custom"] => string(1) "5"
}
[2] => array(2) {
["id"] => string(2) "3"
["custom"] => string(1) "2"
}
}
I want to search for key custom with value = 2, with the following result:
array(2) {
[0] => array(2) {
["id"] => string(2) "1"
["custom"] => string(1) "2"
}
[1] => array(2) {
["id"] => string(2) "3"
["custom"] => string(1) "2"
}
}
Is this possible without looping through array? Is there such class or built in function for this?
You could use:
array_values( array_filter($array, function($item) { return $item['custom'] == 2; }) );
array_values($array) is used to return an array with indexes which is consecutive, i.e. from 0, 1, 2, ... upward.
the array_filter function is probably what you want.
$array = [
[
'id' => '1',
'custom' => '2'
],
[
'id' => '2',
'custom' => '5'
],
[
'id' => '3',
'custom' => '2'
]
];
$customs = array_filter(
$array,
function ($arr) {
return is_array($arr) && array_key_exists('custom', $arr) && $arr['custom'] === '2';
}
);
You could simply remove the values you don't want by un-setting them from the array:
foreach($array as $key => $item) {
if($item['custom'] !== 2) {
unset($array[$key]);
}
}
Example
This is an alternative to array_values(), but essentially does it the same way.

Categories