2

I want to combine 3 small arrays that have unique keys between them into 1 big array but when I modify a value in the big array I want it also to reflect in the corresponding small array.

For example I have these 3 small arrays:

$arr1 = ['key1' => 'data1', 'key2' => 'data2'];
$arr2 = ['key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5'];
$arr3 = ['key6' => 'data6'];

I want to have a $bigArray that has each key's address linked/mapped to each value of the small arrays. So if I do something like:

$bigArray['key4'] = 'something else';

then it would modify $arr2['key4'] to the same value ('something else').

If I try something like:

$bigArray = [&$arr1, &$arr2, &$arr3];

It has the unfortunate effect of making a multidimensional array with the keys to the values mapped.

2
  • Why do you need this? Maybe you can revisit your logic? because there's no simple way to accomplish it. You need to loop over all the arrays and make pointers to actual values. Commented Nov 9, 2016 at 15:01
  • I appreciate the concern, you are right, every solution posted is very costly computation wise but this is my 3rd idea on how to solve my problem and it does not seem to be as cheap as I thought. Commented Nov 9, 2016 at 20:36

2 Answers 2

2

Two ways i found

<?php
error_reporting(E_ALL);

$arr1 = ['key1' => 'data1', 'key2' => 'data2'];
$arr2 = ['key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5'];
$arr3 = ['key6' => 'data6'];

$big = [];
if (true) {
    foreach (['arr1', 'arr2', 'arr3'] as $v) {
        foreach (array_keys($$v) as $k) {
            $big[$k] = &${$v}[$k];
        }
    }
}
else {
    foreach ([&$arr1, &$arr2, &$arr3] as &$v) {
        foreach (array_keys($v) as $k) {
            $big[$k] = &$v[$k];
        }
    }
}


$big['key1'] = 'data1mod';
print_r($big);
print_r($arr1);

3rd way with function

$big = [];
$bindToBig = function (&$a) use (&$big) {
    foreach (array_keys($a) as $k) {
        $big[$k] = &$a[$k];
    }
};

$bindToBig($arr1);
$bindToBig($arr2);
$bindToBig($arr3);
Sign up to request clarification or add additional context in comments.

1 Comment

I especially like your 3rd solution, it very easy to read and understand in a big program. I was hoping that there would be a better solution than simply looping all the arrays but alas, PHP does not have the required constructs.
1

You can't bind data that way, but you can link them in the same object:

class ArrayLink {
    public $bigArray;
    public $linkedChildrenArray;
    protected $childrenArray;

    public function __construct( $childrenArray ) {
        $this->childrenArray = $childrenArray;
    }

    public function changeValueForKey( $arrKey, $arrValue ) {
        foreach ( $this->childrenArray as $key => $value ) {
            foreach ( $value as $subKey => $subValue ) {
                if ( $arrKey == $subKey ) {
                    $this->bigArray[ $subKey ]              = $arrValue;
                    $this->childrenArray[ $key ][ $subKey ] = $arrValue;
                }
            }
        }
        $this->linkedChildrenArray = (object) $this->childrenArray;
    }
}

As you can see, the $arr2 now need to be access from $arrayLink object:

$arr1 = [ 'key1' => 'data1', 'key2' => 'data2' ];
$arr2 = [ 'key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5' ];
$arr3 = [ 'key6' => 'data6' ];

$arrayLink = new ArrayLink( array( 'arr1' => $arr1, 'arr2' => $arr2, 'arr3' => $arr3 ) );
$arrayLink->changeValueForKey( 'key3', 'new value for key 3' );

echo $arrayLink->bigArray['key3']; //new value for key 3
echo $arrayLink->linkedChildrenArray->arr2['key3']; //new value for key 3

1 Comment

Your solution is more a search instead of an actual map of the arrays. I appreciate the ingenuity for suggesting a search but if there are a lot of values to change then your solution becomes expensive computation wise and unfortunately that is my scenario. It would have made sense if I would have to change 1 or max 2 values.

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.