1

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

3
  • Are the keys in the main array important,or is it only the values you're after? Commented Mar 23, 2013 at 18:56
  • Hello @Saeven the new array contains the structure that I need. the keys inside each array of the final array of arrays need to be maintained. the master array index can be 0 based... $finalArray = array( [0]=>array(id=>'123', url=>"xyz.com", data=>"something", data2=>"else", data3=>"baby"), [1]=>array(id=>'456', url=>"abc.com", data=>"something", data2=>"completely", data3=>"different"), [2]=>array(id=>'789', url=>"def.com", data=>"something", data2=>"is not quite", data3=>"right"), ); Commented Mar 23, 2013 at 19:08
  • I can't seem to correct the formatting in the question I posted. the statement "loop again going to $m1[outerloopindex+1] etc" should be step 10, not step 1 indented off step 9. Commented Mar 23, 2013 at 19:13

1 Answer 1

1

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. ;)

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

1 Comment

I will take a look at your answer shortly, thank you for taking the time to explore it :) The criteria is based on a number of requirements 1) id must match, (yes) 2) if both items have different "data2" keys, then take the data2 key from the 1st element and put it into a new named key in the final, and take the data2 key in the 2nd compared element and place it a different named key in the final array as well. but the main goal of matching ids was most important. The array_merge may not be perfect, but a few if...elses may do the trick. maybe also array union or interect related methods?

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.