Anil Astrio
Anil Astrio

Reputation: 103

Reconfigure rows of a 2d array to be columns

How can I convert the below array to look like the one right below. I am trying to use array_map() but I am confused on how to write the function.

array(3) {
  ["award_year"]=>
  array(2) {
    [0]=>
    string(7) "1999-01"
    [1]=>
    string(7) "2010-02"
  }
  ["award_title_user"]=>
  array(2) {
    [0]=>
    string(1) "2"
    [1]=>
    string(2) "tt"
  }
  ["award_description_user"]=>
  array(2) {
    [0]=>
    string(1) "2"
    [1]=>
    string(3) "ddd"
  }
}

This what i am trying to achieve:

array(2) {
  [0]=>
  array(3) {
    ["award_year"]=>
    string(7) "2010-02"
    ["award_title_user"]=>
    string(2) "tt"
    ["award_description_user"]=>
    string(3) "ddd"
  }
  [1]=>
  array(3) {
    ["award_year"]=>
    string(7) "1999-01"
    ["award_title_user"]=>
    string(1) "2"
    ["award_description_user"]=>
    string(1) "2"
  }
}

Upvotes: 0

Views: 72

Answers (2)

Adam Cameron
Adam Cameron

Reputation: 29870

First things first, @tzook-bar-noy's answer is a better answer in this case, and I am not even advocating the approach I am going to detail here.

When dealing with arrays, I always try to avoid generic loops (ie: foreach()) if I can, instead using the more functional-programming approach that you mention in your question: using functions like array_map(). However the functional-programming functions are very focused in what they do (which is their benefit: they make your code Cleaner), so to use them: you kinda gotta be wanting to do the specific operation they offer.

array_map() has a drawback for your purposes here, in that the mapped array has the same keys in the same order as the original array, which is not what you want here. You need to both turn your original array "inside out", but the ordering of the resultant array you want is the reverse of the original data. Not a good fit for array_map().

It's doable with array_map(), but it's like using a flathead screwdriver when you really need a Philips.

Here's an example:

<?php
$awards = [
    "award_year" => ["1999-01", "2010-12"],
    "award_title_user" => ["2", "tt"],
    "award_description_user" => ["2", "ddd"]
];

$remappedAwards = array_map(function($year, $title, $description){
    return [
        "award_year" => $year,
        "award_title_user" => $title,
        "award_description_user" => $description
    ];
}, $awards["award_year"], $awards["award_title_user"], $awards["award_description_user"]);

$remappedAwards = array_reverse($remappedAwards);

echo "<pre>";
var_dump($remappedAwards);
echo "</pre>";

Obviously I've hardcoded the key names in here too which is less than ideal. One could contrive a generic approach, but by then we'd be so far beyond the actual intent of aaray_map() that the code complexity would be getting daft.

In other languages wherein these array-iteration functions are a bit better implemented (say JS or CFML) one might be able to come up with a half-decent answer with a .reduce() (JS, CFML) kind of operation. However PHP's array_reduce() (and its other array-iteration methods) are hamstrung by their poor implementation as they only pass the value to the callback. They really need to pass at least the index as well, and (less-often-useful, but handy sometimes ~) the array itself as additional arguments to make them anything more than a proof-of-concept. IMO, obviously (I'm biased, I do more JS & CFML than I do PHP, so my expectations are set higher).

Bottom line: array_map() was not a good fit for your requirement here, but I applaud your efforts for thinking to us it as the function-programming approach to array manipulation is definitely a better approach than generic looping where the requirement matches the functionality.

Upvotes: 0

Tzook Bar Noy
Tzook Bar Noy

Reputation: 11677

$newArr = [];
foreach($oldArr as $key=>$row) {
   foreach($row as $index=>$item) {
       $newArr[$index][$key] = $item;
   }   
}

this will solve it, but no checks if data is valid as you mentioned

Upvotes: 1

Related Questions