我正在尝试获取从表单输入接收的数据,并在 PHP 中更改其在模板创建模块/应用程序中使用的排序方式。 我需要将它放在多维数组中以供使用。
数组当前的样子
$templateData = [
0 => 'h',
1 => 1,
2 => 2,
3 => 3,
4 => 'c-1-3',
5 => 3,
6 => 5,
7 => 'c-2-3',
8 => 3,
9 => 'c-3-3',
10 => 'f',
11 => 2
];
数组应该是什么样子
$templateData = [
0 =>[ //header row
0 => [1,2,3] //column
],
1 =>[ //content row(s)
0 => [3,5], //column
1 => [3],
2 => [0]
],
2 => [ //footer row
0 => [2] //column
]
]
“h”表示模板标题行的开始,“c-1-3”表示从第一列开始的 3 列行的开始。 “f”代表页脚行的开头。 我现在只是一片空白,无法理解它。
这是我现在所处的位置,但它仍然没有按预期工作:
$elements = $request->input('elements'); //laravel code that grabs array input
$row = 0;
$column = 0;
foreach($elements as $key => $element) {
//if value is a letter
if(preg_match('/^[a-zA-Z]/', $element)) {
//if the 3rd letter in the string is a 1
if(!isset($element[2]) || $element[2] == '1') { $row++; }
//cycle through values after current key
for($i=$key+1; $i < count($elements);$i++){
//until you hit another letter
if(preg_match('/^[a-zA-Z]/', $elements[$i])) { break; }
$column++;
$temp[$row][$column][] = $elements[$i];
}
$column = 0;
}
}
$templateData 和 $elements 变量在上面和下面的上下文中是相同的。
这是我最终得到的代码。 终于明白了。这有效:
//grab input
$elements = $request->input('elements');
//initiate row/column numbers
$row = 0;
$column = 0;
$templateData = array();
//loop through each array value
foreach($elements as $key => $element) {
//if value starts with a letter
if(preg_match('/^[a-z]/', $element)){
//set total columns
if($element != 'h' && $element != 'f')
{
$totalColumns = substr($element, 4);
} else {
$column = 1;
$totalColumns = 1;
}
//if h, c-1-*, or f is detected advance the row
if(substr($elements[$key], 0) == 'h' || substr($elements[$key], 2) == 1 || substr($elements[$key], 0) == 'f')
{
$row++;
}
//loop through keys following first recognized letter until you hit another letter
for($i = $key+1; $i < count($elements) && !preg_match('/^[a-z]/',$elements[$i]); $i++)
{
//add element id to column
$templateData[$row-1][$column-1][] = $elements[$i];
}
//if first value in column is not set, add a 0 value to column
if(!isset($templateData[$row-1][$column-1][0]))
{
$templateData[$row-1][$column-1][0] = 0;
}
//if its the last column in the set, set to 0
if($column == $totalColumns)
{
$column = 0;
}
$column++;
}
}
dd($templateData);
这有点矫枉过正,但你可以拥有全部权力,如果你想改变逻辑,你只需要改变处理程序。希望它能有所帮助。
$templateData = [
0 => 'h',
1 => 1,
2 => 2,
3 => 3,
4 => 'c-1-3',
5 => 3,
6 => 5,
7 => 'c-2-3',
8 => 3,
9 => 'f',
10 => 2
];
$tmpKey = '';
$tmpArray = [];
class Test
{
/**
* @var []
*/
private $data = [];
/**
* @var []
*/
private $columns = [];
/**
* @var array
*/
private $numOfColumns = 0;
/**
* @var []
*/
private $header = [];
/**
* @var []
*/
private $footer = [];
/**
* @var string
*/
private $current = [
'key' => '',
'matches' => ''
];
/**
* @var []
*/
private $rules = [
'header' => [
'expression' => 'h',
'handler' => 'headerHandler',
'matches' => false
],
'footer' => [
'expression' => 'f',
'handler' => 'footerHandler',
'matches' => false
],
'columns' => [
'expression' => 'c-\d+-\d+',
'handler' => 'columnHandler',
'matches' => "columnMatches"
]
];
/**
* @param $data
*/
public function __construct($data)
{
$this->data = $data;
$this->process();
}
/**
* @throws Exception
*/
private function process()
{
foreach($this->data as $data) {
if (!is_int($data)) {
if (!$this->setRule($data)) {
throw new \RuntimeException("Rule Not found.");
}
} else {
$this->handleRule($data);
}
}
}
/**
* @param $data
*/
private function headerHandler($data)
{
$this->header[] = $data;
}
/**
* @param $data
*/
private function footerHandler($data)
{
$this->footer[] = $data;
}
/**
* @param $data
*/
private function columnHandler($data)
{
$columns = explode('-', $this->current['matches']);
if ($this->columns[($columns[1] - 1)][0] == 0){
$this->columns[($columns[1] - 1)][0] = $data;
} else {
array_push($this->columns[($columns[1] - 1)], $data);
}
}
/**
* @param $data
*/
private function columnMatches($data)
{
$columns = explode('-', $data);
if ($this->numOfColumns == 0) {
$this->numOfColumns = end($columns);
$this->columns = array_fill(0, $this->numOfColumns, [0]);
}
}
/**
* @param $data
* @return bool
*/
private function setRule($data)
{
foreach($this->rules as $key => $rules) {
if (preg_match("/^{$rules['expression']}$/", $data, $matches)) {
if ($rules['matches']) {
$this->{$rules['matches']}($data);
}
$this->current['key'] = $key;
$this->current['matches'] = $data;
return true;
}
}
return false;
}
/**
* @return mixed
*/
public function getHeader()
{
return $this->header;
}
/**
* @return mixed
*/
public function getColumns()
{
return $this->columns;
}
/**
* @return mixed
*/
public function getFooter()
{
return $this->footer;
}
/**
* @return array
*/
public function getResult()
{
return [
0 => [$this->header],
1 => $this->columns,
2 => $this->footer
];
}
/**
* @param $data
*/
private function handleRule($data)
{
$this->{$this->rules[$this->current['key']]['handler']}($data);
}
}
$test = new Test($templateData);
echo '<h1>Header</h1>';
var_dump($test->getHeader());
echo '<h1>Footer</h1>';
var_dump($test->getFooter());
echo '<h1>Columns</h1>';
var_dump($test->getColumns());
echo '<h1>Result</h1>';
var_dump($test->getResult());exit;
Ideone:示例在这里
如果将数据推送到引用中,则无需跟踪索引。请参阅内嵌注释以获取信息。
代码:(演示)
$result = [];
foreach ($templateData as $v) {
if (!is_int($v)) {
if (isset($k2) && empty($ref2[$k2])) {
$ref2[$k2][] = 0; // set default 0 if previous group received no values
}
$k2 = $v; // cache the level 2 value
$k1 = strtok($v, '-'); // cache the level 1 value
if (!isset($ref1[$k1])) {
$ref1[$k1] = [];
$result[] =& $ref1[$k1]; // push level 1 reference into result array
}
if (!isset($ref2[$k2])) {
$ref2[$k2] = [];
$ref1[$k1][] =& $ref2[$k2]; // push level 2 reference into level 1 reference
}
} elseif (isset($k2)) {
$ref2[$k2][] = $v; // push integer into level 2 reference
}
}
var_export($result);
输出:
array (
0 =>
array (
0 =>
array (
0 => 1,
1 => 2,
2 => 3,
),
),
1 =>
array (
0 =>
array (
0 => 3,
1 => 5,
),
1 =>
array (
0 => 3,
),
2 =>
array (
0 => 0,
),
),
2 =>
array (
0 =>
array (
0 => 2,
),
),
)