3

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.

1
  • If x is the length of the number, The length of Resultant figure will be having (x *2) -1 items , so you may put zero to the end/ start of each set and sum them up to get the final data items Commented Jul 28, 2021 at 9:32

3 Answers 3

4

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].

Sign up to request clarification or add additional context in comments.

2 Comments

Simple is beautiful
Thats nice, I like it!
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 ) );

1 Comment

This is solution is fine for small data sets. For larger arrays, I would recommend using @mickmackusa answer much more performant.
0

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.

3 Comments

Shouldn't $i < 3 be replaced with $i < count($arr)? Otherwise you're limited to 3 items in the array.
I understood the question as him wanting to be able to change the number on demand, which means that the 3 can become a 300 if he so wishes, I didn't think that he meant it to match the number of elements in the original array, neither am I sure if he wants the arrays to be the same. But re-reading the question does show that he does, meaning I'll just use the count, thanks for the tip.
The question states that OP wants to "duplicate array"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.