代码之家  ›  专栏  ›  技术社区  ›  pauljwilliams

根据父键有选择地展平PHP数组

  •  0
  • pauljwilliams  · 技术社区  · 17 年前

    我需要在PHP中有选择地展平一个数组,但有选择地执行它。如果一个键匹配一个模式,那么该键下面的所有子元素都应该包含在“平面”输出中。

    所以如果我有音乐目录:

    =>专辑数组=>每个专辑都是歌曲标题数组

    然后我可以搜索一个字符串,得到一个响应的平面数组。因此,如果我搜索“sun”,那么我将得到所有以“sun”为名的艺术家的目录,以及其他以“sun”为名的艺术家的专辑。

    希望这是有道理的。

    有人有什么想法吗?

    6 回复  |  直到 17 年前
        1
  •  1
  •   nickf    17 年前

    好吧,我假设你的数据如下:

    $data = array(
        "Bill Withers" => array (
            "Lovely Day",
            "Use Me",
            "Ain't No Sunshine"
        ),
        "Fleet Foxes" => array (
            "Sun It Rises",
            "White Winter Hymnal"
        ),
        "Billy Joel" => array (
            "Piano Man"
        )
    );
    

    …而这给出了输入 "Bill" ,您需要输出: ["Lovely Day", "Use Me", "Ain't No Sunshine", "Piano Man"] . 这是一种方法。

    function getSongs($data, $searchTerm) {
        $output = array();
        foreach ($data as $artist => $songs) {
            if (stripos($artist, $searchTerm) !== false)) {
                $output = array_merge($output, $songs);
            }
        }
        return $output;
    }
    

    …我还认为您有充分的理由不为此使用数据库。

        2
  •  3
  •   Robert S. Barnes Antoni    17 年前

    有没有理由不使用数据库来存储听起来很重要的信息?用SQL编写查询以提取所需的数据是相当简单的。

        3
  •  0
  •   Artem Barger    17 年前

    你的意思是这样的吗?

    $a = array(
        "Sunny" => "Bla-bla1",
        "Sun" => "Bla-bla2",
        "Sunshine" => "Bla-bla3",
    );
    
    foreach ($a as $k => $v) 
    {
     // check here whenever you want for $k
     // apply something to $v
     if ( ... )
          $b[$i++] = $v;
    }
    
        4
  •  0
  •   Eddy    17 年前
    $sample_data = array(  
        'artist_name' => array(  
            'album_name' => array(  
                'song_name',  
                'other_mp3_id_info'  
                )
            )  
        );
    
    function s2($needle,$haystack) {
    
        $threads = array();
        foreach ($haystack as $artist_name => $albums) {
            if (stripos($artist_name, $needle) !== false)) {
                $threads[] = $haystack[$artist_name];   //Add all artist's albums
            } else {
                foreach ($albums as $album_name => $songs) {
                    if (stripos($album_name, $needle) !== false)) {
                        $threads[$artist_name][] = $haystack[$album_name]; //add matching album
                    }
                }
            }
        }
        return $threads;
    }   
    
        5
  •  0
  •   Robert K    17 年前

    为了构建nickf的工作,假设您的数据看起来像他的,我将用这种方式编写函数。

    function getSongs($data, $searchTerm) {
        foreach ($data as $artist => $songs) {
            if (stripos($artist, $searchTerm) !== false)) {
                $output[$artist] = $songs;
            }
        }
        return $output or null;
    }
    

    当找不到匹配项时,此函数的结果将明显返回空值而不是空数组;当找到多个匹配项时,它们将按艺术家分组。我找到了直接任务, $output[$artist] = $songs 以提供比数组合并更可预测的结果。(这还保留了用于输出该数据的艺术家。)

    就像尼克说的,我想你有充分的理由不使用数据库?这方面的SQL非常简单,例如,

    SELECT artist, song FROM songs WHERE artist LIKE '%Bill%' GROUP BY artist;
    
        6
  •  0
  •   soulmerge    17 年前

    你可以使用 preg_grep 对于搜索,请确保清除输入,但是:

    $matchingArtists = preg_grep('/' . preg_quote($searchString) . '/', array_keys($data));
    $matchingSongs = array();
    foreach ($data as $artist => $songs) {
        $matchingSongs = array_merge($matchingSongs, preg_grep('/' . preg_quote($searchString) . '/', $songs));
    }