sum of unique values in array - php

I have below array $billitems_taxes
[0] => Array
(
[id] => 1
[tax_name] => A
[tax_value] => 12
)
[1] => Array
(
[id] => 2
[tax_name] => A
[tax_value] => 8
)
[2] => Array
(
[id] => 3
[tax_name] => B
[tax_value] => 12
)
and I want output as below, find two common tax_name and do some of same and then create a new array.
[0] => Array
(
[id] => 1
[tax_name] => A
[tax_value] => 20
)
[1] => Array
(
[id] => 3
[tax_name] => B
[tax_value] => 12
)
I tried with below code, but it did not return a correct array.
$return_array = [];
foreach($billitems_taxes as $b)
{
$return_array['tax_name'] = $b->tax_name;
$return_array['tax_value'] += $b->tax_value;
}

First off, you have an array of arrays, not objects.
Then your loop needs to know if it has already seen a this tax name which will already be in the new array to check that I used array_key_exists()
$return_array = [];
foreach($billitems_taxes as $b)
{
if ( array_key_exists($b['tax_name'], $return_array) ) {
$return_array[$b['tax_name']]['tax_value'] += $b['tax_value'];
} else {
$return_array[$b['tax_name']] = $b;
}
}
RESULT
Array(
[A] => Array
([id] => 1
[tax_name] => A
[tax_value] => 20
)
[B] => Array
([id] => 3
[tax_name] => B
[tax_value] => 12
)
)
And if its important for the array to be numerically indexed just add
$return_array = array_values($return_array);
after the end of the loop

You must group by 'tax_name' and must sum 'tax_value'.
$billitems_taxes = [
['id' => 1, 'tax_name' => 'A', 'tax_value' => 12],
['id' => 2, 'tax_name' => 'A', 'tax_value' => 8],
['id' => 3, 'tax_name' => 'B', 'tax_value' => 12]
];
$result = [];
foreach($billitems_taxes as $row){
$groupKey = $row['tax_name'];
if(array_key_exists($groupKey,$result)){
$result[$groupKey]['tax_value'] += $row['tax_value'];
} else {
$result[$groupKey] = $row;
}
}
$result = array_values($result);
echo '<pre>';
var_export($result);
/*
array (
0 =>
array (
'id' => 1,
'tax_name' => 'A',
'tax_value' => 20,
),
1 =>
array (
'id' => 3,
'tax_name' => 'B',
'tax_value' => 12,
),
)
*/
The solution with the external class tableArray is very simple. The result is the same.
$result = tableArray::create($billitems_taxes)
->filterGroupAggregate(['tax_value' => 'SUM'],['tax_name'])
->fetchAll()
;

Related

Combine value array in php

i have problem to combine values based on id.
I have data like this :
Array(
[0] => Array(
[id] => 1,
[id_name] => a
[id_vales] => 5
)
[1] => Array(
[id] => 1
[id_name] => a
[id_vales] => 4
)
[2] => Array(
[id] => 3
[id_name] => b
[id_vales] => 4
)
[3] => Array(
[id] => 3
[id_name] => b
[id_vales] => 3
)
)
then, i want combine [id_values] based on id, so i can get data like this in php
Array(
[0] => Array(
[id] => 1
[id_name] => a
[id_vales] => 5, 4
)
[1] => Array(
[id] => 3
[id_name] => b
[id_vales] => 4, 3
)
)
You can use the following example to merge your array
<?php
$mainArray = array(array('id' => 1, 'id_name' => 'a', 'id_vales' => 5),
array('id' => 1,'id_name' => 'a','id_vales' => 4),
array('id' => 3, 'id_name' => 'b','id_vales' => 4),
array('id' => 3,'id_name' => 'b','id_vales' => 3)
);
$result = array();
$tempArray = array();
foreach($mainArray as $key => $value)
{
if(isset($tempArray[$value['id']]))
{
$tempArray[$value['id']] .= ", ".$value['id_vales'];
$result[] = array('id' => $value['id'], 'id_name' => $value['id_name'], 'id_vales' => $tempArray[$value['id']]);
}
else
{
$tempArray[$value['id']] = "".$value['id_vales'];
}
}
echo "<pre>";
print_r($result);
?>
You can find running example here https://paiza.io/projects/3sS3GXH7GHqoipH8k-YtBQ
Output:
Array
(
[0] => Array
(
[id] => 1
[id_name] => a
[id_vales] => 5, 4
)
[1] => Array
(
[id] => 3
[id_name] => b
[id_vales] => 4, 3
)
)
I have created an array for you. from this array you can easily create your array and get the result.
$data = array();
foreach($array as $key=>$value){
$data[$value['id']]['id'] = $value['id'];
$data[$value['id']]['id_vales'][] = $value['id_vales'];
$data[$value['id']]['id_name'] = $value['id_name'];
}

PHP make some of the Key to be sticky in an Associative array

I try to use array_column and array_multisort to sort Array B by Key (ID).
However, I have a scenario whereby I need to have some ID to be sticky on the top .
For example, by comparing Array A and Array B, move ID 3 and ID 1 to the top of the Array B. The final result will be Array C .
Is there a PHP array function to achieve this? Please advice...
Array A
Array
(
[0] => Array
(
[ID] => 3
)
[1] => Array
(
[ID] => 1
)
)
1
Array B
Array
(
[0] => Array
(
[ID] => 1
[product] => A
)
[1] => Array
(
[ID] => 2
[product] => B
)
[2] => Array
(
[ID] => 3
[product] => C
)
[3] => Array
(
[ID] => 4
[product] => D
)
)
1
Array C (Result)
Array
(
[0] => Array
(
[ID] => 3
[product] => C
)
[1] => Array
(
[ID] => 1
[product] => A
)
[2] => Array
(
[ID] => 2
[product] => B
)
[3] => Array
(
[ID] => 4
[product] => D
)
)
1
The preparatory steps involved in generating the lookup and outlier values may be avoidable with more intimate knowledge of your project scope, but I'll only use the values that you have provided. (I mean, you could hardcode outlier as 9999999 and wrap array_flip around array_column for brevity.)
The max value simply needs to be a value higher than the highest ID in the priority array.
The lookup needs to have ID values as keys and their original indexes as the new values (hence the flip).
usort() is precisely the php function to use when performing a custom sorting process.
use is necessary to pass the required additional values into the custom function's scope.
The spaceship operator (<=>) is a fantastic way to package your two-condition sort logic. Each side will be compared using the values "left to right".
Code: (Demo)
$priority = [['ID' => 3], ['ID' => 1]];
$input = [['ID' => 1, 'product' => 'A'], ['ID' => 2, 'product' => 'B'], ['ID' => 3, 'product' => 'C'], ['ID' => 4, 'product' => 'D']];
$lookup = array_column($priority, 'ID');
$outlier = max($lookup) + 1;
$lookup = array_flip($lookup);
usort($input, function($a, $b) use ($lookup, $outlier) {
return [$lookup[$a['ID']] ?? $outlier, $a['ID']] <=> [$lookup[$b['ID']] ?? $outlier, $b['ID']];
});
var_export($input);
Output:
array (
0 =>
array (
'ID' => 3,
'product' => 'C',
),
1 =>
array (
'ID' => 1,
'product' => 'A',
),
2 =>
array (
'ID' => 2,
'product' => 'B',
),
3 =>
array (
'ID' => 4,
'product' => 'D',
),
)
Without the spaceship operator, the custom function gets noticeably more verbose.
Code: (Demo)
usort($input, function($a, $b) use ($lookup, $outlier) {
$bIsPriority = isset($lookup[$b['ID']]);
if (isset($lookup[$a['ID']])) {
if ($bIsPriority) {
return $lookup[$a['ID']] - $lookup[$b['ID']];
} else {
return -1;
}
} elseif ($bIsPriority) {
return 1;
} else {
return $a['ID'] - $b['ID'];
}
});
Here is one of doing it:
<?php
$a = [['ID' => 5], ['ID' => 1]];
$b = [['ID' => 1, 'product' => 'A'], ['ID' => 2, 'product' => 'B'], ['ID' => 3, 'product' => 'C'], ['ID' => 4, 'product' => 'D'], ['ID' => 5, 'product' => 'E']];
// $keysOnTop = Array([0] => 5, [1] => 1)
$keysOnTop = array_column($a, 'ID');
$temp1 = $temp2 = [];
foreach($b as $value){
if(in_array($value['ID'], $keysOnTop)){
$temp1[] = $value;
} else {
$temp2[] = $value;
}
}
// $temp1 = Array([0] => Array([ID] => 1, [product] => A), [1] => Array([ID] => 5, [product] => E))
// $temp2 = Array([0] => Array([ID] => 2, [product] => B), [1] => Array([ID] => 3, [product] => C), [2] => Array([ID] => 4, [product] => D))
$final_arr = array_merge($temp1, $temp2);
echo '<pre>';
print_r($final_arr);
// Output:
/*
Array
(
[0] => Array
(
[ID] => 1
[product] => A
)
[1] => Array
(
[ID] => 5
[product] => E
)
[2] => Array
(
[ID] => 2
[product] => B
)
[3] => Array
(
[ID] => 3
[product] => C
)
[4] => Array
(
[ID] => 4
[product] => D
)
)
*/
?>

How to match key value in two arrays in php [duplicate]

This question already has answers here:
Find intersecting rows between two 2d arrays comparing differently keyed columns
(3 answers)
Closed 4 months ago.
I have two arrays
Array
(
[0] => Array
(
[id] => 1
[affiliate_id] => 190
)
[1] => Array
(
[id] => 2
[affiliate_id] => 946
)
)
Array
(
[0] => Array
(
[id] => 1
[user_id] => 190
)
[1] => Array
(
[id] => 2
[user_id] => 246
)
[2] => Array
(
[id] => 3
[user_id] => 249
)
[3] => Array
(
[id] => 3
[user_id] => 250
)
)
Now i want to get an array which has value like this
if affiliate_id of first array exists in second array as user_id then i will get its value in third array like
Array
(
[0] => Array
(
[affiliate_id] => 190
)
)
i just want affiliate_id which is exists in second array as user_id
$a = Array(
Array('id' => 1, 'affiliate_id' => 190),
Array('id' => 2, 'affiliate_id' => 946)
);
$b = Array(
Array('id' => 1, 'user_id' => 190),
Array('id' => 2, 'user_id' => 246),
Array('id' => 3, 'user_id' => 249),
Array('id' => 3, 'user_id' => 250)
);
$c = array_map(function ($arr) { return $arr['affiliate_id']; }, $a);
$d = array_map(function ($arr) { return $arr['user_id']; }, $b);
$e = array_intersect($c, $d);
print_r($e);
try in_array() with loop
$a = firstarray;
$b = second array;
$i =0;
foreach($b as $k=>$v) {
if(!empty($a[$i])) {
if(in_array($v['user_id'], $a[$i])) {
$c[]['affiliate_id'] = $v['user_id'];
}
}
$i++;
}
print_r($c);
output :-
Array
(
[0] => Array
(
[affiliate_id] => 190
)
)
Use the following code:
<?php
$arr1 = array(array('id' => 1, 'affiliate_id' => 190),
array('id' => 2, 'affiliate_id' => 946));
$arr2 = array(array('id' => 1, 'user_id' => 190),
array('id' => 2, 'user_id' => 246),
array('id' => 3, 'user_id' => 249),
array('id' => 4, 'user_id' => 250));
$count = 0;
foreach ($arr1 as $k1 => $v1) {
if (in_array($v1['affiliate_id'], $arr2[$count]))
{
$arr3[]['affiliate_id'] = $v1['affiliate_id'];
}
$count++;
}
echo '<pre>'; print_r($arr3);
Output
Array
(
[0] => Array
(
[affiliate_id] => 190
)
)

Unset an multidimensional array by key

$series = array();
while($row = mysql_fetch_assoc($result)) {
$series[$row["data_id"]][] = $row;
}
The output from a print_r on $series yields for two example series:
Array (
[1] => Array ( [0] => Array ( [id] => 1 [data_id] => 1 [time_id] => 1
[data] => 1 ) [1] => Array ( [id] => 2 [data_id] => 1 [time_id] => 2
[data] => 3 ) )
[2] => Array ( [0] => Array ( [id] => 6 [data_id] => 2 [time_id] => 1
[data] => 7 ) [1] => Array ( [id] => 7 [data_id] => 2 [time_id] => 2
[data] => 4 ) )
My question: how do I unset the multidimensional array so it contains only [data] and none of the other keys? I still want $series to contain [1] and [2] but I do not want the respective sub-arrays to contain any other keys other than [data].
In fact, since I am reducing the subarrays to contain a single key, I would really like to get rid of the subarrays altogether so that I have two arrays:
$series[1] = array(1,3) and
$series[2] = array(7,4)
Try this :
$series = array();
while($row = mysql_fetch_assoc($result)) {
$series[$row["data_id"]][] = $row['data'];
}
I think you can loop in your array and build a new one keeping only data details
$array = array ('1' => array ( '0' => array ( 'id' => 1, 'data_id' => 1, 'time_id' => 1, 'data' => 1 ), '1' => array ( 'id' => 2, 'data_id' => 1, 'time_id' => 2, 'data' => 3 ), ),
'2' => array ( '0' => array ( 'id' => 6, 'data_id' => 2, 'time_id' => 1, 'data' => 7 ), '1' => array ( 'id' => 7, 'data_id' => 2, 'time_id' => 2, 'data' => 4 ) ));
$i= 0;
$n= 0;
$series = array();
foreach($array as $dato)
{
$series[$i] = array();
foreach($dato as $data)
{
foreach($data as $key => $value)
{
if($key == 'data')
{
$series[$i][$n] = $value;
$n++;
}
}
}
$n = 0;
$i++;
}
var_dump($series);
This will output
array (size=2)
0 =>
array (size=2)
0 => int 1
1 => int 3
1 =>
array (size=2)
0 => int 7
1 => int 4
Live demo

Multidimensional Array Find and Update The Value using PHP

I can't get suitable title for this thread (help me). I can't describe this problem so here the example of my problem.
My array :
Array ( [0] => Array ( [answer] => a [score] => 3 )
[1] => Array ([answer] => b [score] => 4 )
[2] => Array ( [answer] => h [score] => 3)
[3] => Array ( [answer] => a [score] => 4 ))
...
And I wanna get an output like this :
Array ( [0] => Array ( [answer] => a [score] => 7 )
[1] => Array ([answer] => b [score] => 4 )
[2] => Array ( [answer] => h [score] => 3))
...
You can see a change of score subkey in index key 0. This is happen because there is two value 'a' in answer subkey from index key 0 and 3. The score changed to 7 because of the sum of both (3+4). Really I don't have an idea for this, sorry for my english and thanks for help.
Feel free to comment. :)
$merged = array();
foreach ($array as $answer) {
if (isset($merged[$answer['answer']])) {
$merged[$answer['answer']]['score'] += $answer['score'];
} else {
$merged[$answer['answer']] = $answer;
}
}
var_dump($merged);
Check this answer, not using loop :
$arr = array ( array ( 'answer' => 'a', 'score' => 3 ),
array ( 'answer' => 'b', 'score' => 4 ),
array ( 'answer' => 'h', 'score' => 3),
array ( 'answer' => 'a', 'score' => 4 ));
$t = array_reduce($arr, function($result, $item) {
if(array_key_exists($item['answer'],$result)){
$result[$item['answer']] = array('answer' => $item['answer'], 'score' => $item['score']+$result[$item['answer']]['score']);
}
else{
$result[$item['answer']] = array('answer' => $item['answer'], 'score' => $item['score']);
}
return $result;
},array());
echo "<pre>";
print_r($t);
Output :
Array
(
[a] => Array
(
[answer] => a
[score] => 7
)
[b] => Array
(
[answer] => b
[score] => 4
)
[h] => Array
(
[answer] => h
[score] => 3
)
)
I though of using a temporary array:
/* Current array */
$array = array(
array("answer" => "a", "score" => 3),
array("answer" => "b", "score" => 4),
array("answer" => "h", "score" => 3),
array("answer" => "a", "score" => 4)
);
/* Using a temporary array */
$tmp_array = array();
foreach($array as $subarray){
if(array_key_exists($subarray["answer"], $tmp_array)){
$tmp_array[$subarray["answer"]] += $subarray["score"];
}else{
$tmp_array[$subarray["answer"]] = $subarray["score"];
}
}
/* Creating a new formatted array */
$new_array = array();
foreach($tmp_array as $key => $value){
$new_array[] = array("answer" => $key, "score" => $value);
}
print_r($new_array);

Categories