Tetris-ing an array

后端 未结 16 1415
时光取名叫无心
时光取名叫无心 2021-01-30 15:38

Consider the following array:

/www/htdocs/1/sites/lib/abcdedd
/www/htdocs/1/sites/conf/xyz
/www/htdocs/1/sites/conf/abc/         


        
16条回答
  •  死守一世寂寞
    2021-01-30 15:57

    Ok, I'm not sure this is bullet-proof, but I think it works:

    echo array_reduce($array, function($reducedValue, $arrayValue) {
        if($reducedValue === NULL) return $arrayValue;
        for($i = 0; $i < strlen($reducedValue); $i++) {
            if(!isset($arrayValue[$i]) || $arrayValue[$i] !== $reducedValue[$i]) {
                return substr($reducedValue, 0, $i);
            }
        }
        return $reducedValue;
    });
    

    This will take the first value in the array as reference string. Then it will iterate over the reference string and compare each char with the char of the second string at the same position. If a char doesnt match, the reference string will be shortened to the position of the char and the next string is compared. The function will return the shortest matching string then.

    Performance depends on the strings given. The earlier the reference string gets shorter, the quicker the code will finish. I really have no clue how to put that in a formula though.

    I found that Artefacto's approach to sort the strings increases performance. Adding

    asort($array);
    $array = array(array_shift($array), array_pop($array));
    

    before the array_reduce will significantly increase performance.

    Also note that this will return the longest matching initial substring, which is more versatile but wont give you the common path. You have to run

    substr($result, 0, strrpos($result, '/'));
    

    on the result. And then you can use the result to remove the values

    print_r(array_map(function($v) use ($path){
        return str_replace($path, '', $v);
    }, $array));
    

    which should give:

    [0] => /lib/abcdedd
    [1] => /conf/xyz/
    [2] => /conf/abc/def
    [3] => /htdocs/xyz
    [4] => /lib2/abcdedd
    

    Feedback welcome.

提交回复
热议问题