如何使用 PHP 中每个子数组的一个值生成所有可能的组合?
How to generate all possible combinations using one value from each sub-array in PHP?
我有一个看似简单的任务,但我被卡住了。我尝试了重组和迭代器,但没有任何想法让我印象深刻。他们说一张图片胜过一千个字,所以我将展示我的 'picture' 示例数组:
array (size=4)
0 =>
array (size=4)
0 => int 1
1 => int 2
2 => int 3
3 => int 4
1 =>
array (size=3)
0 => string 'a' (length=1)
1 => string 'b' (length=1)
2 => string 'c' (length=1)
2 =>
array (size=3)
0 => string 'X' (length=1)
1 => string 'Y' (length=1)
2 => string 'Z' (length=1)
3 =>
array (size=5)
0 => string '!' (length=1)
1 => string '"' (length=1)
2 => string '#' (length=1)
3 => string '$' (length=1)
4 => string '%' (length=1)
规则:
- 数组大小和子数组大小是随机的,而且相当大。
- 只能使用任何子数组中的一个值。
- 结果应从最短字符串到最长字符串排序。
- 必须是内存高效的,由于正在生成大量数据,结果应该存储/离线比较,如文件或 mysql 数据库。但是一次一个。
所需字符串组合的示例:
1
2
3
4
a
b
c
X ...
1a
1b
1c
2a
2b ...
aX!
aX" ...
1aX!
1aX" .......
4cZ%
我尝试了几个迭代器,比如 How to generate in PHP all combinations of items in multiple arrays。
在我的例子中,解决方案是这个递归函数,我将 $combine
变量切换为首先从数组中插入单个值,然后将合并设置为 true,以合并数据库中的所有值(除了包含当前迭代值的那些):
function iterdb( $arrays, $i = 0, $combine = false ) {
if ( ! isset( array_keys( $arrays )[ $i ] ) ) {
return false;
}
if ( $i == 0 && $combine === true ) {
//Adding empty option to obtain all combos
for ( $x = 0; $x < count( $arrays ); $x ++ ) {
$arrays[ $x ][] = preg_replace( '`=[^\&]+`', '=', $arrays[ $x ][0] );
}
}
$this->iterdb( $arrays, $i + 1, $combine );//Call iteration on each following array
$transactions = array();
sort( $arrays[ $i ] );
$this->log( 'Iterating array ' . $i . ' using combine ' . ( $combine ? 'True' : 'False' ) );
foreach ( $arrays[ array_keys( $arrays )[ $i ] ] as $v ) {
if ( $this->counter > 0 ) {
if ( $combine === false ) {
$transactions[] = "INSERT IGNORE INTO scout_queries (scout,query) VALUES ('" . $this->Class . "','$v')";
} else {
$tmp = $this->queries->find( array(
'scout = :scout and query NOT LIKE :query',
':scout' => $this->Class,
':query' => '%' . ( array_values( explode( '=', $v ) )[0] ) . '%'
), array( 'order' => 'CHAR_LENGTH(query) DESC' ) );
foreach ( $tmp as $t ) {
$transactions[] = "INSERT IGNORE INTO scout_queries (scout,query) VALUES ('" . $this->Class . "','" . $t->query . "&$v')";
$transactions = $this->saveTransactions( $transactions );
}
}
}
$transactions = $this->saveTransactions( $transactions, true );
}
if ( $i == 0 && $combine === false ) {
return $this->iterdb( $arrays, 0, true );
}
}
我有一个看似简单的任务,但我被卡住了。我尝试了重组和迭代器,但没有任何想法让我印象深刻。他们说一张图片胜过一千个字,所以我将展示我的 'picture' 示例数组:
array (size=4)
0 =>
array (size=4)
0 => int 1
1 => int 2
2 => int 3
3 => int 4
1 =>
array (size=3)
0 => string 'a' (length=1)
1 => string 'b' (length=1)
2 => string 'c' (length=1)
2 =>
array (size=3)
0 => string 'X' (length=1)
1 => string 'Y' (length=1)
2 => string 'Z' (length=1)
3 =>
array (size=5)
0 => string '!' (length=1)
1 => string '"' (length=1)
2 => string '#' (length=1)
3 => string '$' (length=1)
4 => string '%' (length=1)
规则:
- 数组大小和子数组大小是随机的,而且相当大。
- 只能使用任何子数组中的一个值。
- 结果应从最短字符串到最长字符串排序。
- 必须是内存高效的,由于正在生成大量数据,结果应该存储/离线比较,如文件或 mysql 数据库。但是一次一个。
所需字符串组合的示例:
1
2
3
4
a
b
c
X ...
1a
1b
1c
2a
2b ...
aX!
aX" ...
1aX!
1aX" .......
4cZ%
我尝试了几个迭代器,比如 How to generate in PHP all combinations of items in multiple arrays。
在我的例子中,解决方案是这个递归函数,我将 $combine
变量切换为首先从数组中插入单个值,然后将合并设置为 true,以合并数据库中的所有值(除了包含当前迭代值的那些):
function iterdb( $arrays, $i = 0, $combine = false ) {
if ( ! isset( array_keys( $arrays )[ $i ] ) ) {
return false;
}
if ( $i == 0 && $combine === true ) {
//Adding empty option to obtain all combos
for ( $x = 0; $x < count( $arrays ); $x ++ ) {
$arrays[ $x ][] = preg_replace( '`=[^\&]+`', '=', $arrays[ $x ][0] );
}
}
$this->iterdb( $arrays, $i + 1, $combine );//Call iteration on each following array
$transactions = array();
sort( $arrays[ $i ] );
$this->log( 'Iterating array ' . $i . ' using combine ' . ( $combine ? 'True' : 'False' ) );
foreach ( $arrays[ array_keys( $arrays )[ $i ] ] as $v ) {
if ( $this->counter > 0 ) {
if ( $combine === false ) {
$transactions[] = "INSERT IGNORE INTO scout_queries (scout,query) VALUES ('" . $this->Class . "','$v')";
} else {
$tmp = $this->queries->find( array(
'scout = :scout and query NOT LIKE :query',
':scout' => $this->Class,
':query' => '%' . ( array_values( explode( '=', $v ) )[0] ) . '%'
), array( 'order' => 'CHAR_LENGTH(query) DESC' ) );
foreach ( $tmp as $t ) {
$transactions[] = "INSERT IGNORE INTO scout_queries (scout,query) VALUES ('" . $this->Class . "','" . $t->query . "&$v')";
$transactions = $this->saveTransactions( $transactions );
}
}
}
$transactions = $this->saveTransactions( $transactions, true );
}
if ( $i == 0 && $combine === false ) {
return $this->iterdb( $arrays, 0, true );
}
}