themis themis - 6 months ago 13
PHP Question

How to convert php object array from one form to another

Is there an easy way to convert an object array from this

stdClass Object
(
[Title] => Array
(
[0] => Title 1
[1] => Title 2
[2] => Title 3
[3] => Title 4
)

[description] => Array
(
[0] => Description 1
[1] => Description 2
[2] => Description 3
[3] => Description 4
)

[myimage] => Array
(
[0] => images/events/568a7048f22f9/sizes/athens-img_XS.jpg
[1] => images/collections/56b2294894c08/islamiki.png
[2] => images/multimedia/item6.jpg
[3] =>
)

)


To this:

stdClass Object
(

[0] => Array
(
[Title] => Title 1
[description] => Description 1
[myimage] => images/events/568a7048f22f9/sizes/athens-img_XS.jpg
)

[1] => Array
(
[Title] => Title 2
[description] => Description 2
[myimage] => images/collections/56b2294894c08/islamiki.png
)

[2] => Array
(
[Title] => Title 3
[description] => Description 3
[myimage] => images/multimedia/item6.jpg
)

[3] => Array
(
[Title] => Title 4
[description] => Description 4
[myimage] =>

)
)

Answer

This is interesting...

Transpose a '2d matrix' - columns into rows. (Realized it did this - months after I wrote it)

  • each output entry consists of an associated array:

  • the key is the property names

  • the data is the 'current column data' for that property

Demonstration at eval.in

Demonstrations of using the function:

1) Original data - call the function.... Eval.in

Now, as long as the data is consistent, as regards number of properties and number of rows of data for each property:

You can change the data without having to change the code.

Two extra properties to each entry and three extra entries... Eval.in

The code:

// ---------------------------------------------------------------------------
// output in here...
$outArray = array();                         // (step 0)

$propsAsArray = get_object_vars($srcObject);  // (step 1) properties as an array

$rowKeys = array_keys($propsAsArray);         // (step 2) we need the the key names

for ($i = 0, $itemCount = count(current($propsAsArray)); $i < $itemCount; $i++) { // (step 3)

    $column = array_column($propsAsArray, $i); // (step 4) get one vertical column through al the arrays

    $entry = array_combine($rowKeys, $column); // (step 5)

    $outArray[] = $entry;                      // (step 6) 
}

$outArray = (object) $outArray;               // (step 7)

As a function:

function convertArray($srcObject) {
    $propsAsArray = get_object_vars($srcObject);  
    $rowKeys = array_keys($propsAsArray);         

    for ($i = 0, $itemCount = count(current($propsAsArray)); $i < $itemCount; $i++) { 

        $outArray[] = array_combine($rowKeys, 
                                    array_column($propsAsArray, $i)); 
    }

    return (object) $outArray;              
}

The output:

stdClass Object
(
    [0] => Array
        (
            [Title] => Title 1
            [description] => Description 1
            [myimage] => images/events/568a7048f22f9/sizes/athens-img_XS.jpg
        )

    [1] => Array
        (
            [Title] => Title 2
            [description] => Description 2
            [myimage] => images/collections/56b2294894c08/islamiki.png
        )

    [2] => Array
        (
            [Title] => Title 3
            [description] => Description 3
            [myimage] => images/multimedia/item6.jpg
        )

    [3] => Array
        (
            [Title] => Title 4
            [description] => Description 4
            [myimage] => 
        )
)

Explanation of the steps.

I will only comment the more involved ones.

Step 1:

We need the property names and data array as an associated array with the property name as the 'key' and the related data.

This is just a 2-dimensional array where the 'keys' are the original property names and the data is an array of the values associated with that property.

Step 2:

Get the 'property names for each output entry'. These are the keys of the array from step 1.

There can be as many as you wish.

Step3:

This is where the work starts...

We are going to take vertical slices through the '2D array'. That is what array_column does.

We need to know how many columns of data that there actually are. However, it is an associated array and we don't know the key names.

Not an an issue:

The 'current function' return the value of the current entry of the 2D array Then just take count of that and store it.

I do it in the initialization part of 'for' loop for efficiency.

Step 4:

We need to get a vertical slice of the current column ($i) through the 2D array.

Step 5:

We now have:

  • a list of keys for the entry ($rowKeys)
  • a data array where each entry matches with the corresponding 'property'

So make the entry and add it to output.

Step 7:

Convert the array back to a stdClass object.

Comments