This question already has answers here:
Associative array, sum values of the same key
(5 answers)
Closed 2 years ago.
I want to sum an array and grouping them by its key value.
this is the array :
Array
(
[0] => Array
(
[delivery_plan] => 80::2020/07
[additional_amount_usd] => 32.88
)
[1] => Array
(
[delivery_plan] => 80::2020/09
[additional_amount_usd] => 16.44
)
[2] => Array
(
[delivery_plan] => 80::2020/07
[additional_amount_usd] => 32.88
)
)
I want output to be like this :
Array
(
[0] => Array
(
[delivery_plan] => 80::2020/07
[additional_amount_usd] => 65.76
)
[1] => Array
(
[delivery_plan] => 80::2020/09
[additional_amount_usd] => 16.44
)
I have tried using this code, but the output different from my expected result :
$arr = [];
foreach ($section_balance as $sb => $val) {
if(array_key_exists($sb, $arr)){
$arr[$sb] += array_sum($val);
} else {
$arr[$sb] = array_sum($val);
}
}
i've got tis result instead :
Array
(
[0] => 112.88
[1] => 96.44
[2] => 112.88
)
How can i solve this ?
This is one way to do it breaking it down into steps...
1.Create the Array that sums the matching delivery_plans
2.Rebuild the Array as required
<?php
$sum_array = [];
foreach($array as $item) {
if (key_exists($item['delivery_plan'], $sum_array)) {
$sum_array[$item['delivery_plan']] += $item['additional_amount_usd'];
} else {
$sum_array[$item['delivery_plan']] = $item['additional_amount_usd'];
}
}
$final_array = [];
foreach($sum_array as $key => $value) {
$final_array[] = ['delivery_plan' => $key, 'additional_amount_usd' => $value];
}
Refactoring the above so the code is not dependant upon hardcoded index names...
$key_name = 'delivery_plan';
$value_name = 'additional_amount_usd';
$sum_array = [];
foreach($array as $item) {
if (key_exists($item[$key_name], $sum_array)) {
$sum_array[$item[$key_name]] += $item[$value_name];
} else {
$sum_array[$item[$key_name]] = $item[$value_name];
}
}
$final_array = [];
foreach($sum_array as $key => $value) {
$final_array[] = [$key_name => $key, $value_name => $value];
}
And you could then turn that into a function if you so desired...
The result is (using var_dump())
array(2) {
[0]=>
array(2) {
["delivery_plan"]=>
string(13) "80::2020 / 07"
["additional_amount_usd"]=>
float(65.76)
}
[1]=>
array(2) {
["delivery_plan"]=>
string(13) "80::2020 / 09"
["additional_amount_usd"]=>
float(16.44)
}
}
Update:
Also Take a look at the solution provided by Kevin.
3v4l.org/h9Q5L
I have this array
[0] => Array
(
[0] => My name
[1] => is
[2] => John
)
[1] => Array
(
[0] => My name is Jane
)
how to achieve this kind of output see below. If the array count is greater than one I want to combine them as one.
[0] => Array
(
[0] => My name is John
)
[1] => Array
(
[0] => My name is Jane
)
here is my code but it didn't work
foreach ($myArr as $key => $value) {
if (count($myArr[$key]) > 1) {
foreach ($value as $k => $v) {
$myArr[$key] .= $v;
}
}
}
thanks
Why not use implode?
$data = [['my name', 'is', 'John'],['my name is Jane']];
$results = [];
foreach ($data AS $id=>$datum)
if (count($datum) > 1)
$results[$id] = implode($datum, ' ');
else
$results[$id] = $datum[0];
results:
array(2) {
[0]=>
string(15) "my name is John"
[1]=>
string(15) "my name is Jane"
}
I suppose it would be like this:
foreach ($myArr as $key => $value) {
if (count($myArr[$key]) > 1) {
$myArr[$key][0] = '';
foreach ($value as $k => $v) {
$myArr[$key][0] .= $v;
}
array_splice($myArr[$key], 1, count($myArr[$key])-1);
}
}
I suppose it would be like this:
$ary[0] = Array("My name","is","John");
$ary[1] = Array( "My name is Jane" );
$i=0;
foreach ($ary as $ar_item) {
$merged="";
foreach ($ar_item as $ar_subitem)
{
$merged=$merged.$ar_subitem." ";
}
$ary[$i]=$merged;
$i++;
}
var_dump($ary);
I have multidimensional array like this. It is in var_dump() formatting.
array(1) {
[4]=>
array(1) {
[2]=>
array(1) {
[5]=>
array(1) {
[1]=>
array(1) {
[3]=>
array(1) {
[6]=>
array(0) {
}
}
}
}
}
}
}
aka $multiArray and i want to get all keys from it and set them to get array like this.
[0=>4, 1=>2, 2=>5, 3=>1, 4=>3, 5=>6] aka **$keysArray**.
Tried like this.
foreach( new \RecursiveIteratorIterator(
new \RecursiveArrayIterator(**$multiArray**),
\RecursiveIteratorIterator::SELF_FIRST)
as $key => $value) {
**$keysArray[]** = $key;
}
also this.
function array_keys_multi(array $array) {
$keys = [];
foreach ($array as $key => $value) {
$keys[] = $key;
if (is_array($value)) {
$keys = array_merge($keys, $this->array_keys_multi($value));
}
}
return $keys;
}
but both of them returns incorrect data. How can i get all keys?
This seems to work for me:
function array_keys_recursive(array $arr) {
foreach($arr as $key => $value) {
$return[] = $key;
if(is_array($value)) $return = array_merge($return, array_keys_recursive($value));
}
return $return;
}
Basically identical to yours, which also works, by the way.
I used a recursive function:
<?php
$multiArray =
array( 4 =>
array (
2 =>
array (
5 =>
array (
1 =>
array (
3 =>
array (
6 =>
array (
)
)
)
)
)
)
);
$keysArray = array();
$depth = 0;
function newArray($array, &$keysArray) {
foreach ($array as $key => $value) {
$depth++;
array_push($keysArray, $key);
if( is_array($value) && $depth < 10 ) { newArray($value, $keysArray ); }
}
}
newArray($multiArray, $keysArray);
print_r( $keysArray ); // Your expected result
// $keysArray = Array ( [0] => 4 [1] => 2 [2] => 5 [3] => 1 [4] => 3 [5] => 6 )
?>
I used the variable $depth to prevent going loop crazy
for a long time can't resolve smth looking like as very simple matter... I want merge a two dimensional arrays.
The example:
$arr1 = {
[532] =
{
[0] = "11"
[1] = "12"
}
[273] =
{
[0] = "99"
}
}
$arr2 = {
[532] =
{
[0] = "11"
[1] = "13"
}
}
And the result of merging should be, a map on common keys, exactly like that array:
$result = {
[532] =
{
[0] =
{
[0] = "11"
[1] = "12"
}
[1] =
{
[0] = "11"
[1] = "13"
}
}
[273]
[0] =
{
[0] = "99"
}
[1] =
{
}
}
I try sometihng like that:
$result = $arr1;
foreach ($arr2 as $key => $value) {
$result[$key] = isset($result[$key]) ? array_merge([$result[$key]], [$value]) : [$value];
}
But it doesnt work if $arr2 is empty :(
For the second array checking, you need to use isset() either array set or not:
Example:
<?php
$arr1 = array('532'=>array('11','12'),'273'=>array('99'));
$arr2 = array('532'=>array('11','13'));
$newArr = array();
foreach ($arr1 as $key => $value) {
if(isset($arr2[$key])){
$newArr[$key][] = $value;
$newArr[$key][] = $arr2[$key];
}
else{
$newArr[$key] = $value;
}
}
echo "<pre>";
print_r($newArr);
?>
Result:
Array
(
[532] => Array
(
[0] => Array
(
[0] => 11
[1] => 12
)
[1] => Array
(
[0] => 11
[1] => 13
)
)
[273] => Array
(
[0] => 99
)
)
Further more, if you want to merge both same index than you can use array_merge() some thing like that:
<?php
$arr1 = array('532'=>array('11','12'),'273'=>array('99'));
$arr2 = array('532'=>array('11','13'));
$newArr = array();
foreach ($arr1 as $key => $value) {
if(isset($arr2[$key])){
$newArr[$key][] = array_merge($value,$arr2[$key]);
}
else{
$newArr[$key] = $value;
}
}
echo "<pre>";
print_r($newArr);
?>
Result:
Array
(
[532] => Array
(
[0] => Array
(
[0] => 11
[1] => 12
[2] => 11
[3] => 13
)
)
[273] => Array
(
[0] => 99
)
)
Note that, ist script, will give you result as you need with unique index.
Second script will give you all values in one single array.
Probably something like this
$arr1 = {
[532] =
{
[0] = "11"
[1] = "12"
}
[273] =
{
[0] = "99"
}
}
$arr2 = {
[532] =
{
[0] = "11"
[1] = "13"
}
}
$newarray = array();
foreach ($arr1 as $key => $value) {
$cu = $arr1[$key];
$newarray[$key][] = $cu;
if(!isset($arr2[$key])) {
$newarray[$key][] = array();
}
else {
$newarray[$key][] = $arr2[$key];
}
}
foreach ($arr2 as $key => $value) {
if(!isset($newarray[$key])) {
$newarray[$key][] = $arr2[$key];
}
}
I have some Problems reducing a multidimensional array into a normal one.
I have an input array like this:
Array
(
[0] => Array (
[0] => 17
[1] => 99
)
[1] => Array (
[0] => 17
[1] => 121
)
[2] => Array (
[0] => 99
[1] => 77
)
[3] => Array (
[0] => 45
[1] => 51
)
[4] => Array (
[0] => 45
[1] => 131
)
So I have a multidimensional array with some overlaps in the values (eg 17,99 and 17,121)
Now I want to have an output like this:
Array
(
[0] => Array (
[0] => 17
[1] => 99
[2] => 121
[3] => 77
)
[2] => Array (
[0] => 45
[1] => 51
[3] => 131
)
I want to save, which articles are the same in my database this way. The output array shpuld still be a multidimesional array, but every number on the second level should be unique in the array.
I'm trying to solve this for more than a week now, but I dont get it to work. I know it should be easy...but anyway - I dont get it :D
This is what i got so far:
$parity_sorted = array();
foreach($arr as $key => $a){
if(count($parity_sorted) > 0){
foreach($parity_sorted as $key2 => $arr_new){
if(in_array($a[0], $arr_new) || in_array($a[1], $arr_new)){
if(!in_array($a[0], $arr_new)){array_push($parity_sorted[$key2], $a[0]);}
if(!in_array($a[1], $arr_new)){array_push($parity_sorted[$key2], $a[1]);}
} else {
array_push($parity_sorted, array($a[0],$a[1]));
}
}
} else {
array_push($parity_sorted, array($a[0],$a[1]));
}
}
Did you maybe already solve problem like this or is there a much easier way? Maybe I just think too complicated (It's not my first try, but this code was the last try)
Any help would be appreciated. Thanks a lot
Here is my revised code given your comment and a DEMO of it working as expected. ( http://codepad.org/CiukXctS )
<?php
$tmp = array();
foreach($array as $value)
{
// just for claraty, let's set the variables
$val1 = $value[0];
$val2 = $value[1];
$found = false;
foreach($tmp as &$v)
{
// check all existing tmp for one that matches
if(in_array($val1, $v) OR in_array($val2, $v))
{
// this one found a match, add and stop
$v[] = $val1;
$v[] = $val2;
// set the flag
$found = true;
break;
}
}
unset($v);
// check if this set was found
if( ! $found)
{
// this variable is new, set both
$tmp[] = array(
$val1,
$val2,
);
}
}
// go trough it all again to ensure uniqueness
$array = array();
foreach($tmp as $value)
{
$array[] = array_unique($value); // this will eliminate the duplicates from $val2
}
ORIGIN ANSWER
The question is badly asked, but I'll attempt to answer what I believe the question is.
You want to gather all the pairs of arrays that have the same first value in the pair correct?
$tmp = array();
for($array as $value)
{
// just for claraty, let's set the variables
$val1 = $value[0];
$val2 = $value[1];
if(isset($tmp[$val1])) // we already found it
{
$tmp[$val1][] = $val2; // only set the second one
}
else
{
// this variable is new, set both
$tmp[$val1] = array(
$val1,
$val2,
);
}
}
// go trough it all again to change the index to being 0-1-2-3-4....
$array = array();
foreach($tmp as $value)
{
$array[] = array_unique($value); // this will eliminate the duplicates from $val2
}
Here is solution for common task.
$data = array(array(17,99), array(17,121), array(99,77), array(45,51), array(45,131));
$result = array();
foreach ($data as $innner_array) {
$intersect_array = array();
foreach ($result as $key => $result_inner_array) {
$intersect_array = array_intersect($innner_array, $result_inner_array);
}
if (empty($intersect_array)) {
$result[] = $innner_array;
} else {
$result[$key] = array_unique(array_merge($innner_array, $result_inner_array));
}
}
var_dump($result);
Try:
$arr = array(array(17,99),
array(17,121),
array(99,77),
array(45, 51),
array(45, 131)
);
foreach($arr as $v)
foreach($v as $m)
$new_arr[] = $m;
$array = array_chunk(array_unique($new_arr), 4);
var_dump($array);
Demo
It uses array_unique and array_chunk.
Output:
array(2) { [0]=>array(4) { [0]=> int(17) [1]=>int(99)
[2]=>int(121) [3]=> int(77) }
[1]=> array(3) { [0]=> int(45) [1]=>int(51)
[2]=>int(131) }
}
I think I get your problem. Let me have a crack at it.
$firstElems = array();
$secondElems = array();
foreach ( $arr as $v ) {
$firstElems[ $v[0] ] = array( $v[0] );
}
foreach ( $arr as $v ) {
$secondElems[ $v[1] ] = $v[0];
}
foreach ( $arr as $v ) {
if ( isset( $secondElems[ $v[0] ] ) ) {
array_push( $firstElems[ $secondElems[ $v[0] ] ], $v[1] );
}
else {
array_push( $firstElems[ $v[0] ], $v[1] );
}
}
foreach ( $firstElems as $k => $v ) {
if ( isset( $secondElems[ $k ] ) ) {
unset( $firstElems[ $k ] );
}
}
Output:
Array
(
[17] => Array
(
[0] => 17
[1] => 99
[2] => 121
[3] => 77
)
[45] => Array
(
[0] => 45
[1] => 51
[2] => 131
)
)
(Code examples: http://codepad.org/rJNNq5Vd)
I truly believe I understand you and if this is the case here is what you're looking for:
function arrangeArray($array) {
$newArray = array(array_shift($array));
for ($x = 0; $x < count($newArray); $x++) {
if (!is_array($newArray[$x])) {
unset($newArray[$x]);
return $newArray;
}
for ($i = 0; $i < count($newArray[$x]); $i++) {
foreach ($array as $key => $inArray) {
if (in_array($newArray[$x][$i], $inArray)) {
$newArray[$x] = array_unique(array_merge($newArray[$x], $inArray));
unset($array[$key]);
}
}
}
$newArray[] = array_shift($array);
}
}
Which will return:
array(2) {
[0]=>
array(4) {
[0]=>
int(17)
[1]=>
int(99)
[2]=>
int(121)
[4]=>
int(77)
}
[1]=>
array(3) {
[0]=>
int(45)
[1]=>
int(51)
[3]=>
int(131)
}
}
For:
var_dump(arrangeArray(array(
array(17,99),
array(17,121),
array(99,77),
array(45, 51),
array(45, 131),
)));
And:
array(1) {
[0]=>
array(6) {
[0]=>
int(17)
[1]=>
int(99)
[2]=>
int(121)
[3]=>
int(45)
[4]=>
int(77)
[6]=>
int(51)
}
}
For:
var_dump(arrangeArray(array(
array(17,99),
array(17,121),
array(99,77),
array(45, 51),
array(45, 17),
)));