3

I have two arrays

$brands = Array (1=>a, 2=>b);
$titles = Array (1=>d, 2=>e);

that I want to convert to one two-dimensional array

$both = Array ( [0] => Array ( [brand] => a, [title] => d ) [1] => Array ( [brand] => b, [title] = d ) );

I can do this using a pair of for loops, each of the form

$key_brand = 0;

foreach ($brands as $brand) {
    $both[$key_brand++]['brand'] = $brand;
}

but this seems clumsy, especially if I want to merge lots of arrays like this. I don't see any standard php function that does what I want. Is there a better way to do it?

jela
  • 1,449
  • 3
  • 23
  • 30
  • Your array examples are some mutants of php and print_r results.. – Kalle H. Väravas Aug 29 '11 at 18:27
  • So you want to merge two arrays and have inner-arrays pushed? Its very hard to understand, what is being asked and your example uses only `$brands` and not `$titles`.. – Kalle H. Väravas Aug 29 '11 at 18:35
  • @Kalle H. Väravas yes, I've got two arrays, and I want to merge them into one array, each of whose elements is itself an array containing one element from each of the two original arrays. The way I'm doing it now is using separate `foreach ($brands as $brand)` and `foreach ($titles as $title)` loops to populate the desired 2-dimensional array with elements from each of the original 1-dimensional arrays, but I'm wondering if there's a cleaner way to do it. – jela Aug 29 '11 at 18:44
  • that makes things more clear. Now, why cant you make them as $both right away? Why must they be separate? – Kalle H. Väravas Aug 29 '11 at 18:46
  • I am getting the data using domdocument() using `$brands = $xpath->query('//li[@class="cp_item"]/a/p[1]');` and `$titles = $xpath->query('//li[@class="cp_item"]/a/p[2]');` which I then convert to arrays as suggested [here](http://de3.php.net/manual/en/class.domnodelist.php#93832). If there's a better way to do it without first creating the 1-dimensional arrays and then combining them, that would certainly be preferable. – jela Aug 29 '11 at 18:53
  • Ok, and are the keys always the same? Also, do the keys start with 1? Because, normally pushed array starts with 0. – Kalle H. Väravas Aug 29 '11 at 18:56
  • the count of each array is the same (ie, count($brands) will be the same as count($title) and so forth). I then iterate through the final array to clean the data before inserting it in a database. Since I'm using `for each $both as $current` to iterate, I figured it doesn't matter whether the array starts on 0 or 1, and it saved a line of code to iterate the counter when setting the relevant value. It's possible that's not good practice. – jela Aug 29 '11 at 19:08
  • In that case, @simshaun answered your question perfectly. Though, this doesnt have anything to do with array pushing, that means something totally other. http://php.net/manual/en/function.array-push.php – Kalle H. Väravas Aug 29 '11 at 19:48

2 Answers2

4

I would start with putting all input information in an array so you know what to loop:

$old = array(
 'brands' => Array (1=>a, 2=>b),
 'titles' => Array (1=>d, 2=>e)
 // etc
);

And then do a double loop:

$new = array();
foreach($old as $key => $value) 
{
  foreach ($value as $num_key => $content)
  {
    $new[$num_key][$key] = $content;
  }
}

An additional advantage is that you preserve your original array keys.

jeroen
  • 91,079
  • 21
  • 114
  • 132
2

Here's something I just wrote that may help. You specify arguments in pairs:

<?php
$brands = array('Foo Global', 'Bar Global');
$titles = array('FooStar 1000', 'BarStar 1000');
$weights = array('400', '600');

function custom_array_merge() {
    $args = func_get_args();
    $arg_len = count($args);

    // Ensure there are no broken pairs. (Not a sophisticated check)
    if ($arg_len < 2 || $arg_len % 2 != 0)
        return FALSE;

    $output = array();

    for ($i = 1; $i <= $arg_len;) {
        $title = $args[$i-1];
        $values = $args[$i];
        foreach ($values AS $key => $value) {
            $output[$key][$title] = $value;
        }
        $i += 2;
    }

    return $output;
}

echo "<pre>";
print_r(custom_array_merge('brand', $brands, 'title', $titles, 'weight', $weights));
echo "</pre>";


Example output:

Array
(
    [0] => Array
        (
            [brand] => Foo Global
            [title] => FooStar 1000
            [weight] => 400
        )

    [1] => Array
        (
            [brand] => Bar Global
            [title] => BarStar 1000
            [weight] => 600
        )

)
simshaun
  • 21,263
  • 1
  • 57
  • 73
  • thanks, I ended up using jeroen's slightly simpler method but this was very interesting to read and worked fine. I've never used func_get_args() before, that's cool. – jela Aug 30 '11 at 16:54