user17516027
user17516027

Reputation:

Convert rows of data into a hierarchical, parent-child structure based on id values

my array:

Array ( 
  [0] => Array (
    [TYPE] => 'Question',
    [PARTY_ID] => 112,
    [PARENT_USER_CONTENT_ID] => ''
  ) 
  [1] => Array (
    [TYPE] => 'Anwser',
    [PARTY_ID] => 115,
    [PARENT_USER_CONTENT_ID] => 112
  ) 
)

What I want:

Array ( 
  [0] => Array ( 
    [TYPE] => 'Question',
    [PARTY_ID] => 112,
    [PARENT_USER_CONTENT_ID] => '',
    [0] => Array (
      [TYPE] => 'Anwser',
      [PARTY_ID] => 115,
      [PARENT_USER_CONTENT_ID] => 112
    ) 
  ) 
)

So the idea is from basic array have questions as array elements and as their subelements anwser that have parent_user_content_Id equals to question party_id.

I tried this:

$new_array = array();
foreach($start_array as $k => $v ){
    if($v['TYPE'] == 'Question'){
        $new_array[] = $v;
    }  
}

In this way, I only get question as elements of new array, I'm struggling with how to add subelements to this.

Upvotes: 0

Views: 52

Answers (2)

lukas.j
lukas.j

Reputation: 7163

This assumes that there is exactly one answer per question:

$arr = [
    [ 'TYPE' => 'Answer', 'PARTY_ID' => 115, 'PARENT_USER_CONTENT_ID' => 114 ],
    [ 'TYPE' => 'Question', 'PARTY_ID' => 112, 'PARENT_USER_CONTENT_ID' => '' ],
    [ 'TYPE' => 'Question', 'PARTY_ID' => 113, 'PARENT_USER_CONTENT_ID' => '' ],
    [ 'TYPE' => 'Answer', 'PARTY_ID' => 116, 'PARENT_USER_CONTENT_ID' => 113 ],
    [ 'TYPE' => 'Question', 'PARTY_ID' => 114, 'PARENT_USER_CONTENT_ID' => '' ],
    [ 'TYPE' => 'Answer', 'PARTY_ID' => 117, 'PARENT_USER_CONTENT_ID' => 112 ]
];

$indexed = array_combine(array_column($arr, 'PARTY_ID'), $arr);
$answers = array_flip(array_filter(array_column($arr, 'PARENT_USER_CONTENT_ID', 'PARTY_ID')));

foreach ($answers as $parentPartyId => $childPartyId) {
  $result[] = array_merge($indexed[$parentPartyId], [ 'ANSWER' => $indexed[$childPartyId]]);
}

print_r($result);

Test on 3v4l

Upvotes: 1

Dula
Dula

Reputation: 1412

You can use 2 loops to process the questions first and then the answers.

$new_array = array();

// first loop to process the questions
foreach($start_array as $arr){

    // add questions to the $new_array first
    if ($arr['TYPE'] == "Question"){

        $new_array[] = [
            'TYPE' => $arr['TYPE'],
            'PARTY_ID' => $arr['PARTY_ID'],
            'PARENT_USER_CONTENT_ID' => $arr['PARENT_USER_CONTENT_ID',
            'ANSWERS' => []
        ];
    }
}

// second loop to process answers
foreach($start_array as $arr2){

    // add answers to the $new_array by matching the IDs
    if ($arr2['TYPE'] == "Anwser"){

        $parentQuestionId = $arr2['PARENT_USER_CONTENT_ID'];

        // looping through our new question array to find the correct parent question
        foreach($new_array as &$question){

            if ($question['PARTY_ID'] == $parentQuestionId) {

                // adding the answer to the correct parent question
                $question['ANSWERS'][] = $arr2;

            }
        }
    }
}

Using 2 loops seems like a exaggeration but it allows you to account for all the answers without missing a single one.

Upvotes: 0

Related Questions