DJ Eddie J
DJ Eddie J

Reputation: 113

php merge elements in an array of arrays with common and different keys into a final array

Suppose I have single array of arrays. each element in the array of arrays are similar to each other as they have similar keys, but perhaps one of the keys has a unique value or one of the arrays in the array of arrays has an additional/different key. For example...

$masterArray = array( 
     [0]=>array(id=>'123', url=>"http://xyz.com", data=>"something", data2=>"else"),
     [1]=>array(id=>'123', url=>"http://xyz.com", data=>"something", data3=>"baby"),
     [2]=>array(id=>'456', url=>"http://abc.com", data=>"something", data2=>"completely"),
     [3]=>array(id=>'456', url=>"http://abc.com", data=>"something", data3=>"different"),
     [4]=>array(id=>'789', url=>"http://def.com", data=>"something", data2=>"is not quite"),
     [5]=>array(id=>'789', url=>"http://def.com", data=>"something", data3=>"right")
 );

I require a new array to be made from $masterArray that would merge the individual keys together in the array of arrays into a new key in the new array, based on matching key value pairs in each individual array. So the final array would appear like this...

$finalArray = array(
    [0]=>array(id=>'123', url=>"http://xyz.com", data=>"something", data2=>"else", data3=>"baby"),
    [1]=>array(id=>'456', url=>"http://abc.com", data=>"something", data2=>"completely", data3=>"different"),
    [2]=>array(id=>'789', url=>"http://def.com", data=>"something", data2=>"is not quite", data3=>"right"),
);

There's quite an array (no pun intended) of php functions that can sort / merge arrays or values, but I cannot figure out which ones to use or how to implement it!

Can anyone figure out a solution to this? It would be much appreciated.

Note: To note, I have done the following

What I have tried is the following algorithm:

  1. create two copies of $masterArray (call them $m1 and $m2)
  2. use two for..each loops. The first for...each loop goes through $m1, the second one through $m2
  3. grab the current element in $m1 from the outer loop
  4. compare the current element in $m2 from the inner loop
  5. if the $m1[outerloopindex] matches $m2[innerloopindex] through the majority of their key values, create a new array element $x, merging their key value pairs.
  6. push or add $x to $newArray
  7. (and this may or may not work) remove the element compared from $m1 and $m2 (since we used them, we don't need them anymore. assume no more matches)
  8. if the $m1[outerloopindex] does not match$m2[innerloopindex] , simply go to the next $m2[innerloopindex] value and compare again to $m1[outerloopindex] until a match is made (or not)
  9. if no elements in $m2 match the element compared against in $m1, keep $m1[outerloopindex]
    1. loop again going to $m1[outerloopindex+1] etc.

But unfortunately it does not seem to return the correct number of results :(

Sample code is below.

    foreach($artistData as $key=>&$asset){
        // 2. examine each element, its value is itself an array.
        // $key returns the position
                    // reset the $artistData array
        $artistData=array_values($artistData);
        $currElement = $artistData[$key];           
                    // 3. check for this secondary array's uid. 
                    // loop through each element in this secondary array
        $currElUid = $currElement['uid'];
        $currElid = $currElement['id'];
        $currElThumbUrl = $currElement['thumbUrl'];

             // 4. then proceed down the remaining array  and compare the remaining indice's array's uid with the current one being explored
        $artistCount=0;
        // reset the second array $artistData02;
        $artistData02 = array_values($artistData02);
        foreach($artistData02 as $key02=>&$asset02){
                            // clear our temporary new element
            unset($resultElement);
            $resultElement=array(); 
            // grab the new element to compare to. 
                            // make sure it's not the same as the original
            $newCurrElement = $artistData02[$key02];
            $newCurrElUid = $newCurrElement['uid'];
            $newCurrElid = $newCurrElement['id'];
            $newCurrElThumbUrl = $newCurrElement['thumbUrl'];

            // if I already compared this element, then skip it entirely
            // We also don't want to compare the element to itself.
            if ($key!=$key02){

                // make sure the uids match
                if($currElUid==$newCurrElUid){
                    // make sure the thumb URLs are different
                    if($currElThumbUrl!=$newCurrElThumbUrl){
                        //  create the new merged element
                        // grab the filetype of $currElement
                        switch($currElement['filetype']){
                            case 1:
                            $resultElement['imageLge']=$currElement['publicUrl'];
                            $resultElement['imageSml']=$currElement['thumbUrl'];
                            break;
                            case 3:
                            $resultElement['song']=$currElement['publicUrl'];
                            break;
                        }
                        // then we compare the newCurrElement and add our information
                        switch($newCurrElement['filetype']){
                            case 1:
                            $resultElement['imageLge']=$newCurrElement['publicUrl'];
                            $resultElement['imageSml']=$newCurrElement['thumbUrl'];
                            break;
                            case 3:
                            $resultElement['song']=$newCurrElement['publicUrl'];
                            break;
                        }
                        // for the remaining values, we will pass as is
                        $resultElement['title']=$currElement['title'];
                        $resultElement['uid']=$currElement['uid'];

                        // take the resultant $resultElement and merge it to the main array (before $resultELement is recreated)
                        array_push($resultArr,$resultElement);

                        // this will reflow the elements, and change the indexing(so the echo merge statement will change). but comparisons will be reduced
                        unset($artistData[$key]);
                        $artistData = array_values($artistData);
                        unset($artistData02[$key02]);
                        $artistData02 = array_values($artistData02);




                    }else{
                        //echo "The thumbURLs are the same. skipping... <br />";
                    }
                }else{
                //echo "not the same uids. skipping... <br />";
                }
            }else{
                //echo "this is the same element. skipping... <br />";
            }

        $artistCount++;
        // end inner for...each loop
        }






    // 7. loop and check through the remaining elements in main array again.
    }
    /* end outer for each loop */


    // add another element - the artist count at the end
    $resultArr['artistCount']= $artistCount-1;
    // build a JSON object that contains the artists, the total number
    echo $resultArr;

again, any help is appreciated...

Upvotes: 1

Views: 2431

Answers (1)

Saeven
Saeven

Reputation: 2300

To answer your original question, this code will intake your masterArray and output your finalArray:

// sample array just for completeness
$masterArray = array(
        array('id'=>'123', 'url'=>"http://xyz.com", 'data'=>"something", 'data2'=>"else"),
        array('id'=>'123', 'url'=>"http://xyz.com", 'data'=>"something", 'data3'=>"baby"),
        array('id'=>'456', 'url'=>"http://abc.com", 'data'=>"something", 'data2'=>"completely"),
        array('id'=>'456', 'url'=>"http://abc.com", 'data'=>"something", 'data3'=>"different"),
        array('id'=>'789', 'url'=>"http://def.com", 'data'=>"something", 'data2'=>"is not quite"),
        array('id'=>'789', 'url'=>"http://def.com", 'data'=>"something", 'data3'=>"right")
);

// here's where the code actually begins
$finalArray = array();
foreach( $masterArray as $m )
{
    if( !isset( $finalArray[$m['id']] ) )
        $finalArray[$m['id']] = $m;
    else
        $finalArray[$m['id']] = array_merge( $finalArray[$m['id']], $m );
}
$finalArray = array_values( $finalArray );

If you var_dump $finalArray, it'll line up with what you wanted to get. This is matching based on id.

Your sample code I haven't taken the time to read thoroughly, is aggregating values based on id enough? If so, answer is above. ;)

Upvotes: 1

Related Questions