Алгоритм динамического слияния массивов - PullRequest
4 голосов
/ 21 декабря 2011

Я пытаюсь создать оператор INSERT для каждой строки в объекте PHPExcel. Поскольку я изо всех сил пытался выполнить итерацию по столбцу (т. Е. Перейти в B1 C1 D1, получить значения и поместить их в массив), я решил получить все значения для каждого столбца и поместить их в многомерный массив, который выглядит так:

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
        )
)

Я хочу объединить каждый из массивов, чтобы все данные с индексом 0 находились в одном массиве и т. Д. Я создал универсальный инструмент, позволяющий выбирать нужные столбцы из загруженной электронной таблицы. Сначала необходимо объединить данные столбца в один массив, а затем сгенерировать операторы INSERT для каждого из массивов. Итак, окончательный результат таков:

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

Вся помощь приветствуется.

ОБНОВЛЕНИЕ: Привет всем, большое спасибо за ваши ответы. Мне наконец удалось заставить его работать, используя итераторы строк и ячеек согласно предложению Марка, и это работает У меня сейчас есть отдельная проблема, но я думаю, что это то, что я могу решить. Еще раз спасибо.

Ответы [ 5 ]

1 голос
/ 21 декабря 2011

Вы можете использовать один из этих странных итераторов для этого:)

$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);
}

Но на самом деле простой цикл for - это инструмент, который можно использовать здесь.

1 голос
/ 21 декабря 2011
$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;
}
1 голос
/ 21 декабря 2011
<code><?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.'
'; ;

Обратите внимание, что вам может потребоваться внести некоторые корректировки из соображений производительности, если значение $uberArray велико (например, разбить строку вставки на куски). Или вы можете преобразовать данные в CSV и использовать метод MySQL LOAD DATA INFILE, который очень быстрый.

1 голос
/ 21 декабря 2011

Не уверен, что это то, что вы хотели, но ...

<?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);

Редактировать: хотя я думаю, что вы пропустили имя таблицы в ваших операторах INSERT.

Edit2: Вы можете сократить код, используя array_keys, как это делает Frosty Z, и пропустить первый foreach.

0 голосов
/ 21 декабря 2011

Я не вижу причин для объединения массива, если вы не хотите тратить память.Вы, вероятно, уже сделали копию данных.Это просто вставляет данные строка за строкой.

$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);
}

Я бы на самом деле использовал подготовленные операторы.

И вы действительно должны попытаться выяснить, как перебирать исходный набор данных за один проход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...