从平面阵列和结构化ID构建阵列树 [英] Build an array tree from flat array and structured ID

查看:102
本文介绍了从平面阵列和结构化ID构建阵列树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



 <$ c 

如果您对此问题的第二个问题感到困惑,请耐心等待,因为我不确定这个问题确实有意义。 $ c> 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并做< h1> ,1.1有< h2> 但是当涉及到4.1.x时,请打开一个< ul> 并给每个规则一个< li>



为此,我最好的方法是选择数据,比如我最终得到的数组:

 数组(4 => 
数组(4.1 =>
数组(4.1.1 =>'规则内容')

);

然后,我可以实现我的深度并打开< ul> 标签,通过打印出该深度的规则等循环。



什么是解决这个问题的最佳方法?我已经看了很多年了,不知道该从哪里出发去说实话。我真的希望数据在同一个表中。我想我可以解决这个问题,如果他们都在不同的表中,但我不知道这肯定会更容易。



我开始了这条路线:

  foreach($ m as $ rule){
$ depth = count(explode('。',$ rule [ 'ruleid']));
switch($ depth){
case 1:
echo'< h1>'。$ rule ['content']。'< / h1>';
休息;
案例2:
echo'< h2>。$ rule ['content']。'< / h2>';
休息;
案例3:
echo'< strong>'。$ rule ['content']。'< / strong>';
休息;
}
echo'< br /> \\\
';
}

然后我意识到这只是单独处理每个规则条目,而我的解决方案需要对规则中的位置进行某种感知,因此它可以知道何时打开标记(例如< ul> ),然后完成后再次关闭回显可能出现在规则中的列表项(例如不要做:< ul>< li>此< / li>< li>或< ; / li>>< / ul>



以下是上述数据表中所需输出的示例:


0。简介



...



4。聊天



4.1。做和不做



4.1.1。做:



  • 4.1.1.9保持礼貌
  • 4.1.1.10保持耐心
  • 4.1.1.11聪明

希望一些明亮的火花可以帮到你!

方案

假设,从你的输入数据中,你可以产生一个像这样的数组:

pre $ $ $ $ $ $ data =数组(
'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'=>'内容4.1.1.10',
'4.1.1.11'=>'内容4.1.1.11',
);

然后,您可以通过以下方式转换为树状结构:

  //这将是我们的根节点
//它没有内容,但是有一个地方给孩子
$ struct = array(
'children'=> array()
);

foreach($ data as $ ruleID => $ content){
// / \
// ||
//对于输入数据中的每个规则id,我们以
//根
// ||开始
// \ /
$ parent =& $结构;

//我们在点处分割$ ruleID得到一条路径,我们遍历
// ||
// \ /
foreach(爆炸('。',$ ruleID)为$ val){

//对于路径中的每个条目,我们
//检查它是否在当前父元中可用
// ||
// \ /
if(!isset($ parent ['children'] [$ val])){
//如果不是,我们创建一个空条目
$ parent ['children'] [$ val] = array(
'content'=>'',// no content
'children'=> array()// no children
);
}

// / \
// ||
//然后使用新的或已存在的父
//作为新的父元
// ||
// ||请介意参考作业!这
// \ /是最重要的部分
$ parent =& $父[孩子] [$ VAL]
}

//遍历整个路径后,我们可以
//最后添加我们的内容
// ||
// \ /
$ parent ['content'] = $ content;
}

print_r($ struct);

演示: http://codepad.org/vtMPjGoa


Hold fire if you are confused by the question a second on the question because I'm not sure that it exactly makes sense.

SELECT * FROM `rules` ORDER BY `Rank_1` , `Rank_2` , `Rank_3` , `Rank_4` ASC

Yields:

Copy pasta:

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

However this data is not quite in a form I need it to be in order to do something useful with it.

I want to loop through all the rules and depending on how 'deep' I am, do different things. For example I'd like to take RuleID = 0 and do <h1>, 1.1 have <h2> but when it comes to 4.1.x, open up a <ul> and give each rule an <li>.

For this I figure the best way is to select the data like an array where I'd end up with:

array( 4 =>
    array( 4.1 =>
        array( 4.1.1 => 'rule content')
    )
);

Then I could realise my depth and open up a <ul> tag, loop through printing out the rules at that depth etc.

What is really the best way to tackle this? I've been at it for ages and don't have a clue where to go from here to be honest. I really want the data to be in the same table. I figure I could probably solve this if they were all in different tables but I don't know that for sure it would be any easier.

I started down this route:

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';
}

Then I realised this is just going to deal with each rule entry individually, whereas my solution needs some sort of 'awareness' of where it is in the rules, so it can know when to open a tag (such as a <ul>) and then close it again when it's done echoing list items that might be present in a rule (such as "Don't do: <ul><li>this</li><li>or this</li></ul>")

Here's an example of desired output from the table of data above:

0. Introduction

...

4. Chat

4.1. Do's and do not's

4.1.1. Do:

  • 4.1.1.9 Be polite
  • 4.1.1.10 Be patient
  • 4.1.1.11 Be smart

Hope some bright spark can help!

解决方案

Suppose, from your input data, you can produce an array like this:

$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',
);

which you could then transform to a tree-like structure with this:

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

demo: http://codepad.org/vtMPjGoa

这篇关于从平面阵列和结构化ID构建阵列树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆