Php 从平面阵列和结构化ID构建阵列树
如果你被这个问题弄糊涂了,就不要发火,因为我不确定这个问题是否有意义Php 从平面阵列和结构化ID构建阵列树,php,mysql,html,Php,Mysql,Html,如果你被这个问题弄糊涂了,就不要发火,因为我不确定这个问题是否有意义 SELECT * FROM `rules` ORDER BY `Rank_1` , `Rank_2` , `Rank_3` , `Rank_4` ASC 收益率: 复制意大利面: 0 0 0 0 0 1 0 0 0 1 1 1 0 0 1.1 1 1 1 0 1.1.1 2 0 0 0 2 4 0 0 0 4 4 1 0
SELECT * FROM `rules` ORDER BY `Rank_1` , `Rank_2` , `Rank_3` , `Rank_4` ASC
收益率:
复制意大利面:
0 0 0 0 0
1 0 0 0 1
1 1 0 0 1.1
1 1 1 0 1.1.1
2 0 0 0 2
4 0 0 0 4
4 1 0 0 4.1
4 1 1 0 4.1.1
4 1 1 9 4.1.1.9
4 1 1 10 4.1.1.10
4 1 1 11 4.1.1.11
然而,这些数据并不是完全以我需要的形式出现,以便对它做一些有用的事情
我想循环所有的规则,根据我的“深度”,做不同的事情。例如,我想取RuleID=0并执行
,1.1有
,但当涉及到4.1.x时,打开一个
,并给每个规则一个
对于这一点,我认为最好的方法是选择数据,就像选择一个数组一样,我最终会得到:
array( 4 =>
array( 4.1 =>
array( 4.1.1 => 'rule content')
)
);
然后我可以意识到我的深度,打开一个
标签,循环打印出该深度的规则等
解决这个问题的最佳方法是什么?说实话,我已经做了很多年了,不知道从这里该怎么办。我真的希望数据在同一个表中。我想如果他们都在不同的表格中,我可能会解决这个问题,但我不确定这会更容易
我沿着这条路线出发:
foreach($m as $rule) {
$depth = count(explode('.', $rule['ruleid']));
switch($depth) {
case 1:
echo '<h1>'.$rule['content'].'</h1>';
break;
case 2:
echo '<h2>'.$rule['content'].'</h2>';
break;
case 3:
echo '<strong>'.$rule['content'].'</strong>';
break;
}
echo '<br />\n';
}
foreach($m作为$rule){
$depth=count(分解('.',$rule['ruleid']);
交换机(深度){
案例1:
回显'.$rule['content'].';
打破
案例2:
回显'.$rule['content'].';
打破
案例3:
回显“”.$rule['content']”。;
打破
}
回音“
\n”;
}
然后我意识到这只是要单独处理每个规则条目,而我的解决方案需要某种“意识”它在规则中的位置,这样它就可以知道何时打开标记(例如
),然后在完成回显规则中可能存在的列表项(例如“不要这样做:- 这个
- 或者这个
”
)
以下是上述数据表中所需输出的示例:
0.导言
4.聊天
4.1.应做和不应做的事
4.1.1.应:
- 4.1.1.9礼貌点
- 4.1.1.10耐心点
- 4.1.1.11聪明点
我不确定这是否正是你所需要的,但也许它会给你一些想法 首先,您可以通过以下操作确定规则的“深度”:
$depth = count(explode('.',$rule_id));
$data = array(
'0' => 'content 0',
'1' => 'content 1',
'1.1' => 'content 1.1',
'1.1.1' => 'content 1.1.1',
'2' => 'content 2',
'4' => 'content 4',
'4.1' => 'content 4.1',
'4.1.1' => 'content 4.1.1',
'4.1.1.9' => 'content 4.1.1.9',
'4.1.1.10' => 'content 4.1.1.10',
'4.1.1.11' => 'content 4.1.1.11',
);
这将在
上拆分规则id并生成一个数组。然后对数组中的项目进行计数以确定深度。假设您可以从输入数据生成如下数组:
$depth = count(explode('.',$rule_id));
$data = array(
'0' => 'content 0',
'1' => 'content 1',
'1.1' => 'content 1.1',
'1.1.1' => 'content 1.1.1',
'2' => 'content 2',
'4' => 'content 4',
'4.1' => 'content 4.1',
'4.1.1' => 'content 4.1.1',
'4.1.1.9' => 'content 4.1.1.9',
'4.1.1.10' => 'content 4.1.1.10',
'4.1.1.11' => 'content 4.1.1.11',
);
然后,您可以使用以下方法将其转换为树状结构:
// this will be our root node
// it has no content, but a place for children
$struct = array(
'children' => array()
);
foreach ($data as $ruleID => $content) {
// /\
// ||
// for every rule id in the input data we start at
// the root
// ||
// \/
$parent =& $struct;
// we split $ruleID at the dot to get a path, which we traverse
// ||
// \/
foreach (explode('.', $ruleID) as $val) {
// for every entry in the path we
// check if it's available in the current parent
// ||
// \/
if (!isset($parent['children'][$val])) {
// if not, we create an empty entry
$parent['children'][$val] = array(
'content' => '', // no content
'children' => array() // no children
);
}
// /\
// ||
// and then use either the new, or allready existent parent
// as the new parent
// ||
// || mind the assignment by reference! this
// \/ is the most important part
$parent =& $parent['children'][$val];
}
// after the whole path is traversed, we can
// finally add our content
// ||
// \/
$parent['content'] = $content;
}
print_r($struct);
演示:如果您想将HTML与SQL混合在一起,可能会破坏各种样式规则,您可以添加一个“ruledepth”列,然后在其上使用“CASE”,例如:
选择othercols,
案例
当ruledepth=0时,则为CONCAT(“”,ruleid“”)
当ruledepth=1时,则为CONCAT(“”,ruleid“”)
当ruledepth=2时,则为CONCAT(“”,rileid“ ”)
等
从XXX结束,其中……按规则ID订购。。。。。。。。
对OPs代码进行轻微修改
您可以将$rule['ruleid']
添加到echo语句中,使其与所需的输出完全一致
$hasList=false;
foreach($m as $rule) {
$depth = count(explode('.', $rule['ruleid']));
// end previous list before starting with new rules
if ($hasList && $depth<4) {
echo '</ul>';
$hasList=false;
}
switch($depth) {
case 1:
echo '<h1>'.$rule['content'].'</h1>';
break;
case 2:
echo '<h2>'.$rule['content'].'</h2>';
break;
case 3:
echo '<strong>'.$rule['content'].'</strong>';
break;
case 4:
// start list if not already started
if (!$hasList) {
echo '<ul>';
$hasList=true;
}
echo '<li>'.$rule['content'].'</li>';
break;
}
//echo "<br />\n";
}
// end last list
if ($hasList) {
echo '</ul>';
$hasList=false;
}
$hasList=false;
foreach(通常为百万美元){
$depth=count(分解('.',$rule['ruleid']);
//在开始新规则之前结束上一个列表
如果($hasList&&$depthmaybe如果你解释了你想用这个来完成什么,我们会更好地帮助你。你能添加一个输入数据的可复制版本吗?手工编写这个只是为了让原型运行有点烦人;)太少的细节无法给出任何真正的答案。你也可以按RuleID排序,因为。“好了,你去Yoshi。不,我不能Imre,因为1<9和MySQL不能自然排序。也就是说,字符对字符,我已经做了什么来确定深度。但这条路线还不够。太好了!我想这样做,但我担心会浪费时间。”因为我不够好(很高兴您的代码会指出这一点,因为我不知道如何像您一样使用$struct
)所以首先来这里。非常感谢,能够用PHP来做这件事比试图在多个表中处理数据要好得多。这是解释代码工作原理的正确地方吗?我非常感谢,我相信这会帮助别人。我在上一次尝试解决这个问题时(几个月前)确实提出了这个问题但我认为这不是最好的解决方案,因为我希望深度完全可变,甚至在某些情况下,在其他
中也有
等。很抱歉,我没有指定。