Algorithm to dynamically merge arrays

纵饮孤独 提交于 2019-12-12 11:54:21

问题


I'm trying to create a INSERT statement for every row in a PHPExcel object. As I've struggled to iterate across the column (ie. go B1 C1 D1, get the values, and put them into an array), I've opted to get all the values for each column and put them into a multi-dimensional array that looks like this:

Array
(
    [foo] => Array
        (
            [0] => 250
            [1] => 247
            [2] => 279
            [3] => 249
        )

    [bar] => Array
        (
            [0] => AM PROV
            [1] => AM PROV
            [2] => AM PENS
            [3] => AM PROV
        )

    [schoo] => Array
        (
            [0] => xxxx
            [1] => yyy
            [2] => zzz
            [3] => aaa
        )
)

I want to merge each of the arrays so that all the data at index 0 is in one array, etc. I've built a generic tool to allow you to select the columns you want from an uploaded spreadsheet. It needs to first merge the column data into a single array and then it should generate INSERT statements for each of the arrays. So the final deliverable is this:

INSERT INTO (foo, bar, schoo) VALUES (250, "AM PROV", "xxxx");

All help appreciated.

UPDATE: Hey all, thank you very much for your answers. I finally managed to get it working using row and cell iterators as per Mark's suggestion and it's working. I have a separate issue with it now, but I think it's something I can solve. Thanks again.


回答1:


<?php
$uberArray = array(
    "foo" => array(
        0 => 250,
        1 => 247,
        2 => 279,
        3 => 249,
    ),
    "bar" => array(
        0 => "AM PROV",
        1 => "AM PROV",
        2 => "AM PENS",
        3 => "AM PROV",
    ),
    "schoo" => array(
        0 =>  "xxxx",
        1 =>  "yyy",
        2 =>  "zzz",
        3 =>  "aaa",
    )
);

$yourMysqlLink = mysql_connect('localhost', 'user', 'pass');
mysql_query('SET NAMES utf8'); // Adjust according to your encoding

$colNames = array_keys($uberArray);
$stringCols = array('bar', 'schoo');
$sqlInsertStr = 'INSERT INTO `your_table` (`'.implode('`, `', $colNames)."`) VALUES \n";

$rows = array();
// Not really for iterating the first array, we just need a loop
foreach ($uberArray[$colNames[0]] as $k => $v) {
    $vals = array();
    foreach ($colNames as $v2) {
        $val = $uberArray[$v2][$k];
        if (in_array($v2, $stringCols)) {
            $val = "'".mysql_real_escape_string($val, $yourMysqlLink)."'";
        }
        $vals[] = $val;
    }
    $rows[] = "\t(".implode(', ', $vals).")";
}
$sqlInsertStr .= implode(",\n", $rows).';';

echo '<pre style="clear:both;">'.$sqlInsertStr.'</pre>'; ;

Note that you may need to do a few adjustments for performance reasons, if $uberArray is big (e.g. splitting the insert string into chunks). Or you can convert the data to CSV and use MySQL LOAD DATA INFILE method, which is real fast.




回答2:


Not sure if this is what you were after but...

<?php
# Given this array
$arrays = array(
    'foo' => array(
        0 => 250, 
        1 => 247, 
        2 => 279, 
        3 => 249
    ), 
    'bar' => array(
        0 => 'AM PROV', 
        1 => 'AM PROV', 
        2 => 'AM PENS', 
        3 => 'AM PROV'
    ), 
    'schoo' => array(
        0 => 'xxxx', 
        1 => 'yyy', 
        2 => 'zzz', 
        3 => 'aaa'
    )
);

# This code generates...
$fields = array();
$inserts = array();

foreach ($arrays as $k => $v) {
    $fields[] = $k;
}

for ($i = 0; $i < count($arrays[$fields[0]]); $i++) {
    $vals = array();

    foreach ($fields as $field) {
        $vals[] = $arrays[$field][$i];
    }

    $inserts[] = 'INSERT INTO (' . implode(',', $fields) . ') VALUES ("' . implode('","', $vals) . '")';
}

# This array
/* $inserts = array(
    'INSERT INTO (foo, bar, schoo) VALUES ("250", "AM PROV", "xxxx")', 
    'INSERT INTO (foo, bar, schoo) VALUES ("247", "AM PROV", "yyy")', 
    'INSERT INTO (foo, bar, schoo) VALUES ("279", "AM PENS", "zzz")', 
    'INSERT INTO (foo, bar, schoo) VALUES ("249", "AM PROV", "aaa")'
); */

var_dump($inserts);

Edit: Though I think you're missing a table name from your INSERT statements.

Edit2: You could shorten the code using array_keys like Frosty Z does and skip the first foreach.




回答3:


$inputArray = array('a' => array(1, 2, 3), 'b' => array("X'", 'Y', 'Z'));
$finalArray = array();

// build array with appropriate data rows

$finalIndex = 0;

foreach($inputArray as $key => $row)
{
  foreach($row as $value)
    $finalArray[$finalIndex][] = $value;

  $finalIndex++;
}

// format it as SQL insert queries

$fields = array_keys($inputArray);

foreach($finalArray as $row)
{
  echo "INSERT INTO table (".implode(", ", $fields).") "
    . " VALUES (".implode(", ", array_map("format_data", $row)).");\n";
}

function format_data($value)
{
  // assuming you're using MySQL. Replace the escape function by
  // the appropriate one
  if (is_string($value))
    return "'".mysql_real_escape_string($value)."'";
  else
    return $value;
}



回答4:


You can use one of those strange spl iterators for this :)

$iter = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC);
foreach ($uberArray as $colName => $colValues) {
    $iter->attachIterator(new ArrayIterator($colValues), $colName);
}

foreach ($iter as $vals) {
    print_r($vals);
    //or $pdoStmt->execute($vals);
}

But really, a simple for loop is the tool to use here.




回答5:


I see no reason to merge the array unless you feel like wasting memory. You've already probably made a copy of the data. This just inserts the data row by row.

$data = array('foo' => array(...), ... );
$fields = array('foo', 'bar', 'schoo');
$c = count($data[$fields[0]));

$base_sql = 'INSERT INTO tbl ('.implode(',', $fields).') VALUES ';

for ($i = 0; $i < $c; ++$i)
{
  $row_data = array();
  foreach ($fields as $field)
     $row_data[] = "'".escape_func($data[$field][$i])."'";

  $sql = $base_sql . '(' . implode(',', $row_data). ')';
  db_query($sql);
}

I would actually use prepared statements.

And you really should try to figure out how to iterate through the original dataset in one pass.



来源:https://stackoverflow.com/questions/8591808/algorithm-to-dynamically-merge-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!