【问题标题】:Concatenate the values from one array to another in PHP在 PHP 中将一个数组中的值连接到另一个数组
【发布时间】:2016-01-20 12:50:29
【问题描述】:

我正在尝试创建一个函数来生成特定字符组的所有可能组合,并根据长度使其可变。

我有一个函数可以创建一个我想要的字符数组,这很好用。

function generate_characters($l, $n, $d) {
    $r = array();

    if ($l === true) {
        foreach (range('a', 'z') as $index) {
            array_push($r, $index);
        }
    }

    if ($n === true) { array_push($r, '0','1','2','3','4','5','6','7','8','9'); }


    if ($d === true) { array_push($r, '-'); }

    return $r;
}

然后我需要让它根据 $length 创建一个包含所有可能组合的数组,例如如果 '$length = 1' 我需要以下数组

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
    [5] => f
    [6] => g
    [7] => h
    [8] => i
    [9] => j
    [10] => k
    [11] => l
    [12] => m
    [13] => n
    [14] => o
    [15] => p
    [.... removed some values to save on length ....]
    [35] => 9
)

但是如果 '$length = 2' 我需要这个

Array
(
    [0] => aa
    [1] => ab
    [2] => ac
    [3] => ad
    [4] => ae
    [5] => af
    [6] => ag
    [7] => ah
    [8] => ai
    [9] => aj
    [.... removed some values to save on length ....]
    [1329] => 97
    [1330] => 98
    [1331] => 99
)

我尝试了 array_walk() 和 array_walk_recursive(),以及几个 foreach 和 while 循环,但无济于事。

我可以通过手动为每个长度执行它来使其工作,但不能通过这样做来使用可变长度,但不知道如何使其按长度可变。

function generate_two($l, $n, $d) {
    $r = array();

    foreach (generate_characters($l, $n, false) as $v1) {
        foreach (generate_characters($l, $n, $d) as $v2) {
            array_push($results, "$v1$v2");
        }
    }
    return $r;
}

虽然没有将“-”作为第一个字符,但如果需要,我可以在生成数组后删除这些值。

谢谢,丹

【问题讨论】:

  • $r = array(); foreach (range('a', 'z') as $index) { array_push($r, $index); } 只是写$r = range('a', 'z');的复杂方式
  • 谢谢@axiac,我这样做是因为我可能只想要数字,而不是字母

标签: php arrays concatenation concat string-concatenation


【解决方案1】:

假设您想使用您创建的数组作为用于追加的数组。我不明白为什么您需要使用数组中以外的特定字符(我可能错了,但这很容易适应这种情况)。

/**
 * @param array $array
 * @param $length
 * @param null $original
 * @return array
 */
function generate_values(array $array, $length, $original = null) {

    // If length is 1 or less just return the array
    if ($length <= 1) {
        return $array;
    }

    // The resulting values array
    $result = [];

    // Copy the array if original doesn't exist
    if (!is_array($original)) {
        $original = $array;
    }

    // Loop over each item and append the original values
    foreach($array as $item) {
        foreach($original as $character) {
            $result[] = $item . $character;
        };
    }

    // Recursively generate values until the length is 1
    return generate_values($result, --$length, $original);
}

要使用它,您可以使用您的生成器。

$characterArray = generate_characters(true, false, false);

$results = generate_values($characterArray, 2);

【讨论】:

    【解决方案2】:

    我不知道这是否是最好的解决方案,但是:

    function generate_characters($length, $n, $d, $array = array()) {
        $letters = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9');
        $numbers = range(0, 9);
        $others = array('-');
    
        if($n == true)
            $letters = array_merge($letters, $numbers);
    
        if($d == true)
            $letters = array_merge($letters, $others);
    
    
        if(empty($array))
            $array = $letters;
    
        if(--$length <= 0)
            return $array;
    
        $result = array();
        foreach ($array as $value) {
            foreach ($letters as $add) {
                $result[] = $value.$add;
            }
        }
    
        return generate_characters($length, $n, $d, $result);
    }
    
    echo '<pre>';
    print_r(generate_characters(3, true, true));
    

    【讨论】:

    • 这行得通,但是我将 $numbers 范围更改为 0-9,否则您会得到类似 'aa10' 的结果,并且没有考虑到我可能不想要字母 :D
    【解决方案3】:

    示例代码

    function generate_characters($l, $n, $d)
    {
        // Start with an empty list
        $r = array();
    
        // Add the letters, if required
        if ($l) {
            $r = array_merge($r, range('a', 'z'));
        }
        // Add the digits, if required
        if ($n) { 
            $r = array_merge($r, range('0', '9'));
        }
        // Add special characters, if required
        if ($d) { 
            $r[] = '-';
        }
    
        return $r;
    }
    
    
    /**
     * Generate all combinations of $len characters using the characters
     * from a given list
     *
     * @param array $chars  the list of characters to use
     * @param int   $len    the length of strings to generate
     * @return array
     */
    function generate_combinations(array $chars, $len)
    {
        // $len <= 0: this is an error
        // $len == 1: the input list is the output
        if ($len <= 1) {
            return $chars;
        }
    
        // Compute the output here
        $result = array();
    
        // Recursively compute the list of characters of length $len - 1
        $partial = generate_combinations($chars, $len - 1);
    
        // Append each entry from the input list to each string of length $len - 1 computed on the previous step
        foreach ($partial as $head) {
            foreach ($chars as $tail) {
                // Put the combination in the output list
                $result[] = $head.$tail;
            }
        }
    
        // This is the list of all strings of length $len over the list $chars
        return $result;
    }
    

    用法

    没有必要一次又一次地打电话给generate_characters()。给定相同的参数,它总是返回相同的字符列表。将其保存在变量中,进一步使用该变量。

    $chars = generate_characters(TRUE, FALSE, TRUE);
    $comb2 = generate_combinations($chars, 2);
    $comb5 = generate_combinations($chars, 5);
    

    备注

    虽然理论上是正确的,但生成所有组合在现实生活中完全没用。组合的数量呈指数增长,很快您的脚本将使用所有可用内存来存储列表。

    我测试了上面的代码,PHP 5.6 需要超过 2 GB 的内存来生成 5 个字符的所有组合(使用字母 + 破折号)。 PHP 7 更好地使用内存,并且它需要少于 1 GB 的内存来完成相同的任务。

    如您所想,不可能为参数$len 使用更高的值;即使是$len == 5,上面列出的金额也已经很大了。

    【讨论】:

    • 我正在尝试创建所有可能的域名组合,与密码无关
    • 好吧,在这种情况下,我将从答案中删除该部分。
    • 内存量是个问题,但对于我的任务来说,这是一个必要的邪恶,我可以在更大的 EC2 实例上运行它,每个长度只需要运行一次,然后将值存储在数据库中,并根据这些值进行进一步处理
    【解决方案4】:

    如果你想组合两个数组的值,你可以直接使用这段代码。您不需要函数中该数组的长度。

    function generateValue($array1, $array2) {
        $result = array();
        foreach ($array as $value) {
            foreach ($original as $value2) {
                $result[] = $value.$value2;
            }
        }
    
        return $result;
    }
    print_r(generateValue($array1, $array2));
    

    【讨论】:

    • 这就是我在generate_ll函数中所做的,并没有考虑到可变长度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多