PHP: 以树状结构保存数据
PHP: Save data in tree structure
我有一个 Excel 看起来很简单:
如果我阅读它 (编辑:我使用 PHPExcel),我会为每一行得到一个如下所示的数组:
$row = [Process, MainScrenario, Process1, Step1] // first row
$row = [null, null, null, Step2] // second row
现在我有多个 Excel-files,每个都有不同数量的列。
我试图找到一种方法,将 Excel 的多个 $row-Arrays 解析为一个大数组,其中 tree-structure 或类似的东西,以存储信息。
有人可以帮我吗?我应该怎么做?
我试图将上面的评论编成一个编码示例。修改此以满足您的需求:
<?php
// prepare data
$data = array(
['Process', 'MainScenario', 'Process1', 'Step1'],
[null, null, null, 'Step2'],
[null, null, null, 'Step3'],
[null, null, null, 'Step3'],
[null, null, 'Process2', 'Step1'],
[null, null, null, 'Step2'],
[null, 'SecScenario', 'Process1', 'Step1'],
[null, null, null, 'Step2'],
[null, null, 'Process2', 'Step1'],
[null, null, null, 'Step2'],
[null, null, null, 'Step3'],
);
// define class which holds the nodes
class node {
private $text = ''; // the text (name) of the node
private $children = array(); // list of the children of the node
function __construct($text) { // constructor. sets the text
$this->text = $text;
}
function addChild(&$ref) { // add a child
$this->children[] = $ref; // store reference to child in $this->children array property
}
function getText() { // get text of the node
return $this->text; // retrieve textdomain
}
function getChildren() { // get children of the node
return $this->children; // fetch & deliver array
}
function __toString() { // magic function for conversion to string
return $this->getText(); // is an alias for $this->getText
}
}
// parse the data into a tree
function buildTree($data) {
$start = array(); // list of all root nodes
$last = array(); // list of last-seen nodes on every depth
foreach ($data as $row) { // iterate over all rows
$depth = 0; // reset depth (start form left)
foreach ($row as $cell) { // iterate over all cells in the row
if (!is_null($cell) && $cell!='') { // empty cell? if so, ignore
if ($depth==0) { // top layer?
$obj = new node($cell.' (R)'); // this is a root node
$start[] = $obj; // add to list of root nodes
$last[0] = $obj; // set as root node
}
else {
$parent = null; // we want to find a parent object
for ($dd = $depth-1; $dd>=0; $dd--) { // traverse up to root
if (isset($last[$dd])) { // $last for this level set?
$parent = $last[$dd]; // accept it as parent
break; // do not search further
}
}
if (!is_null($parent)) { // parent found?
$obj = new node($cell.' ('.$depth.')'); // create new node for this entry
$parent->addChild($obj); // attach it to the parent
$last[$depth] = $obj; // set object as $last for this level
}
}
}
$depth++; // increase depth (advance right)
}
}
return $start; // return list of root nodes
}
// show the tree descending from a single node given
function showTree($node, $depth = 0) { // recursively output nodes
echo str_repeat('> ', $depth).$node->getText().PHP_EOL; // this node
foreach ($node->getChildren() as $subnode) { // iterate over child nodes
showTree($subnode, $depth+1); // recursive call for children
}
}
// execute
$rootNodes = buildTree($data); // build the tree
foreach($rootNodes as $node) { // iterate over root nodes
showTree($node); // show tree for each of them
}
?>
产生:
Process (R)
> MainScenario (1)
> > Process1 (2)
> > > Step1 (3)
> > > Step2 (3)
> > > Step3 (3)
> > > Step3 (3)
> > Process2 (2)
> > > Step1 (3)
> > > Step2 (3)
> SecScenario (1)
> > Process1 (2)
> > > Step1 (3)
> > > Step2 (3)
> > Process2 (2)
> > > Step1 (3)
> > > Step2 (3)
> > > Step3 (3)
括号中的数字是添加节点的实际 $depth
级别。 (R) 表示根节点。
查看演示 here。
我有一个 Excel 看起来很简单:
如果我阅读它 (编辑:我使用 PHPExcel),我会为每一行得到一个如下所示的数组:
$row = [Process, MainScrenario, Process1, Step1] // first row
$row = [null, null, null, Step2] // second row
现在我有多个 Excel-files,每个都有不同数量的列。
我试图找到一种方法,将 Excel 的多个 $row-Arrays 解析为一个大数组,其中 tree-structure 或类似的东西,以存储信息。
有人可以帮我吗?我应该怎么做?
我试图将上面的评论编成一个编码示例。修改此以满足您的需求:
<?php
// prepare data
$data = array(
['Process', 'MainScenario', 'Process1', 'Step1'],
[null, null, null, 'Step2'],
[null, null, null, 'Step3'],
[null, null, null, 'Step3'],
[null, null, 'Process2', 'Step1'],
[null, null, null, 'Step2'],
[null, 'SecScenario', 'Process1', 'Step1'],
[null, null, null, 'Step2'],
[null, null, 'Process2', 'Step1'],
[null, null, null, 'Step2'],
[null, null, null, 'Step3'],
);
// define class which holds the nodes
class node {
private $text = ''; // the text (name) of the node
private $children = array(); // list of the children of the node
function __construct($text) { // constructor. sets the text
$this->text = $text;
}
function addChild(&$ref) { // add a child
$this->children[] = $ref; // store reference to child in $this->children array property
}
function getText() { // get text of the node
return $this->text; // retrieve textdomain
}
function getChildren() { // get children of the node
return $this->children; // fetch & deliver array
}
function __toString() { // magic function for conversion to string
return $this->getText(); // is an alias for $this->getText
}
}
// parse the data into a tree
function buildTree($data) {
$start = array(); // list of all root nodes
$last = array(); // list of last-seen nodes on every depth
foreach ($data as $row) { // iterate over all rows
$depth = 0; // reset depth (start form left)
foreach ($row as $cell) { // iterate over all cells in the row
if (!is_null($cell) && $cell!='') { // empty cell? if so, ignore
if ($depth==0) { // top layer?
$obj = new node($cell.' (R)'); // this is a root node
$start[] = $obj; // add to list of root nodes
$last[0] = $obj; // set as root node
}
else {
$parent = null; // we want to find a parent object
for ($dd = $depth-1; $dd>=0; $dd--) { // traverse up to root
if (isset($last[$dd])) { // $last for this level set?
$parent = $last[$dd]; // accept it as parent
break; // do not search further
}
}
if (!is_null($parent)) { // parent found?
$obj = new node($cell.' ('.$depth.')'); // create new node for this entry
$parent->addChild($obj); // attach it to the parent
$last[$depth] = $obj; // set object as $last for this level
}
}
}
$depth++; // increase depth (advance right)
}
}
return $start; // return list of root nodes
}
// show the tree descending from a single node given
function showTree($node, $depth = 0) { // recursively output nodes
echo str_repeat('> ', $depth).$node->getText().PHP_EOL; // this node
foreach ($node->getChildren() as $subnode) { // iterate over child nodes
showTree($subnode, $depth+1); // recursive call for children
}
}
// execute
$rootNodes = buildTree($data); // build the tree
foreach($rootNodes as $node) { // iterate over root nodes
showTree($node); // show tree for each of them
}
?>
产生:
Process (R)
> MainScenario (1)
> > Process1 (2)
> > > Step1 (3)
> > > Step2 (3)
> > > Step3 (3)
> > > Step3 (3)
> > Process2 (2)
> > > Step1 (3)
> > > Step2 (3)
> SecScenario (1)
> > Process1 (2)
> > > Step1 (3)
> > > Step2 (3)
> > Process2 (2)
> > > Step1 (3)
> > > Step2 (3)
> > > Step3 (3)
括号中的数字是添加节点的实际 $depth
级别。 (R) 表示根节点。
查看演示 here。