使用PHP从现有多维数组的特定值创建新数组

时间:2014-01-07 17:51:43

标签: php arrays multidimensional-array

简短项目说明:我需要从现有数组输出特定值,以进行选项卡式字母导航。导航将几个字母组合成标签(即“A-C”),然后显示以这些字母开头的帖子的所有链接。导航是由插件创建的,因此我需要创建变量来输出组。

我拥有的东西:我有一个数组,它按子数组的name键按字母顺序排序。它看起来像以下示例:

Array (
  [0] => Array ( 
    ['name'] => 'Alpha'
    ['link'] => 'http://www.someurl.com' 
  )    

  [1] => Array ( 
    ['name'] => 'Alpha2'
    ['link'] => 'http://www.someotherurl.com' 
  )     

  [2] => Array ( 
    ['name'] => 'Beta'
    ['link'] => 'http://www.someurl.com' 
  )

  [3] => Array ( 
    ['name'] => 'Delta'
    ['link'] => 'http://www.someotherurl.com' 
  )

  [4] => Array ( 
    ['name'] => 'Zephyr'
    ['link'] => 'http://www.someurl.com' 
  )
)

我认为需要发生什么:我需要创建5个新的数组,按字母顺序对这些子数组进行分组。意思是,我需要将name以'A'开头的所有数组 - 'C'放到一个数组中,'D' - 'G'放到另一个数组中等等。

换句话说,上面显示的数组会导致创建以下内容:

$a_c = array(
  [0] => Array ( 
    ['name'] => 'Alpha'
    ['link'] => 'http://www.someurl.com' 
  )    
  [1] => Array ( 
    ['name'] => 'Alpha2'
    ['link'] => 'http://www.someotherurl.com' 
  )     
  [2] => Array ( 
    ['name'] => 'Beta'
    ['link'] => 'http://www.someurl.com' 
  )   
);

$d_g = array(
  [0] => Array ( 
    ['name'] => 'Delta'
    ['link'] => 'http://www.someotherurl.com' 
  )
);
$h_l = array();
$m_r = array();
$s_t = array();
$u_z = array(
  [0] => Array ( 
    ['name'] => 'Zephyr'
    ['link'] => 'http://www.someurl.com' 
  )
);

如果将新的数组值(如[5] => Array (['name'] => 'Kappa' ['link'] => 'http://www.someurl.com'))添加到第一个数组,则会将其添加到$h_l变量中的数组中。

有谁知道如何做到这一点?

4 个答案:

答案 0 :(得分:1)

这是使用最终输出数组而不是许多不同范围数组的一种方法。

循环遍历原始数组,确定第一个字母落入哪个预定义范围,将当前条目添加到最终输出数组的适当范围。

// define ranges
$ranges=array(
    'A-C'=>range('A','C'),
    'D-G'=>range('D','G'),
    'H-K'=>range('H','K'),
    'L-O'=>range('L','O'),
    'P-S'=>range('P','S'),
    'T-W'=>range('T','W'),
    'X-Z'=>range('X','Z')
);

// build final array with each entry in its appropriate range
$final=array();
foreach ($data as $item) {
    $first_letter=strtoupper(substr($item['name'],0,1));
    foreach ($ranges as $label => $range) {
        if (in_array($first_letter,$range)) {
            $final[$label][]=$item;
            break;
        }
    }
}

// output the final array
echo"<pre>".print_r($final,true)."</pre>";

这是输出:

Array
(
    [A-C] => Array
        (
            [0] => Array
                (
                    [name] => Alpha
                    [link] => http://www.someurl.com
                )

            [1] => Array
                (
                    [name] => Alpha2
                    [link] => http://www.someotherurl.com
                )

            [2] => Array
                (
                    [name] => Beta
                    [link] => http://www.someurl.com
                )

        )

    [D-G] => Array
        (
            [0] => Array
                (
                    [name] => Delta
                    [link] => http://www.someotherurl.com
                )

        )

    [X-Z] => Array
        (
            [0] => Array
                (
                    [name] => Zephyr
                    [link] => http://www.someurl.com
                )

        )

)

http://phpfiddle.org/main/code/w06-sc5

答案 1 :(得分:0)

如果确定哪个值进入哪个数组的标准只是名称,是否有任何理由不能只使用foreach()循环主数组并且模式匹配第一个字符?或者,您可以使用substr()将第一个字符保存到变量,然后在switch()测试中与此匹配。如果它纯粹是一对一的安排(即你为字母表的每个字母设置了不同的数组),那么你可以使用动态命名的变量来建立关联。

答案 2 :(得分:0)

好的,我写下了我的想法。使用$$我将访问参数化的变量名称。从我基于实际“name”参数的信息开始生成值(例如$ a_c,$ d_f,ecc ...)。

变量名称为:

我得到实际[“name”]值的起始字母(带substr)。使用ord(),我在ascii中获得了相应的值。

除以/ 3并乘以3,我得到它所属的“字母组”的第一个字母(例如:如果第一个字母是“B”,我将得到“a”的“a” “)。

此值+ 2是最后一个字母。

我追加这两个信息,转回chr()的字符串。

我根本没有测试过,这是一个伪代码示例:

foreach ($myarray as $value)
{
    //finding the name of the variable. the variable name is derived by the letter of the actual value["name"]. the last letter is the first + 2. the name is divided by an underscore.
    $first_letter = intval((substr(ord($value["name"], 0, 1)) - ord('A')) / 3)*3 + ord('A');
    $last_letter = $first_letter + 2;
    $var_name = chr($first_letter)."_".chr($first_letter);
    if (!isset($$var_name))
        $$var_name = array();
    $$var_name[] = $value;
}

答案 3 :(得分:0)

试试这个功能。此函数由两个参数组成,一个是您要搜索的字母,另一个是源数组。

function getNewArray($letter='A',$arr){
  if(!is_array($arr)) return;
  $result=array();
  foreach($arr as $a){
    if( strtolower(trim($a['name'][0])) === strtolower($letter)){
            $result[] = $a; 
    }
  }
  return $result;
}

//此函数返回一个名称以字母m开头的数组。第一个参数是NOT区分大小写 getNewArray('M',$array); //这里$ array是你的源数组。