I have values 1,2,3 and it will create another value like below and produce results by summing. As there are 3 values so that it will create three arrays. if it were 5 values then 5 such arrays are required.
1 2 3
1 2 3
1 2 3
Result is : 1 3 6 5 3
What I am doing is :
$a=[1,2,3];
$b=$a;
$c=$a;
$d=[];
array_push($a,0,0);
array_unshift($b,0);
array_push($b,0);
array_unshift($c,0,0);
$d = array_map(function () {
return array_sum(func_get_args());
}, $a,$b,$c);
print_r($d);
I am not able to find the way to do this for more values than 3 and dynamically. So that I have to just put the values and it gives me the result. I am not asking for the code but you can help me with that how I should approach it. Thanks.
I recommend a linear approach with no preparations or padding or data bloat.
Use the indexes and simple arithmetic to add values to their desired element in the output.
Code: (Demo)
$array = range(1, 3);
$result = [];
foreach ($array as $shifter => $unused) {
foreach ($array as $index => $value) {
$key = $shifter + $index;
$result[$key] = ($result[$key] ?? 0) + $value;
}
}
var_export($result);
// [1, 3, 6, 5, 3]
This is very clean, readable, maintainable, and most efficient.
While $shifter = 0, $key will be 0, 1 then 2; forming [1, 2, 3].
While $shifter = 1, $key will be 1, 2 then 3; forming [1, 3, 5, 3].
While $shifter = 2, $key will be 2, 3 then 4; forming [1, 3, 6, 5, 3].
If you're using PHP 7.4+ you can use the below...
// Ensure the keys are indexed not associative.
$input = array_values( [ 1, 2, 3, 4, 5 ] );
// Create rows.
$rows = [];
foreach ( $input as $key => $value ) {
$rows[ $key ] = array_merge( array_fill( 0, $key, 0 ), $input );
}
// Sum values.
$output = array_map( function() {
return array_sum( func_get_args() );
}, ...$rows );
If you're using a PHP version below 7.4 you can do...
// Ensure the keys are indexed not associative.
$input = array_values( [ 1, 2, 3 ] );
// Create rows.
$rows = [];
foreach ( $input as $key => $value ) {
$rows[ $key ] = array_merge( array_fill( 0, $key, 0 ), $input );
}
// Sum values.
$output = call_user_func_array( 'array_map', array_merge( [ function() {
return array_sum( func_get_args() );
} ], $rows ) );
I'm thinking using an offset makes sense, it's the same as your approach, except I'm adding a 0 using array_fill
$arr = [1,2,3];
$result = [];
$offset = 0;
for($i = 0; $i < count($arr); $i++) {
$result = array_map(function () {
return array_sum(func_get_args());
}, $result, array_merge(array_fill(0, $offset, 0), $arr));
$offset++;
}
var_dump($result);
The advantage of using this is that it uses very little memory even for a very large initial array.