values recursively recursive read multidimensional index from buscar array_values array php arrays recursion multidimensional-array

recursively - PHP 2D Array genera todas las combinaciones



php get value from array (11)

En la base de datos MySQL sería así:

SELECT * FROM `options`, `groups`

Eso es todo :)

He tenido este problema que hace que mi mente se incline por un tiempo (¡la cabeza fría tampoco ayuda!), Básicamente tengo una matriz PHP que se ve como este ejemplo:

$array[0][0] = ''apples''; $array[0][1] = ''pears''; $array[0][2] = ''oranges''; $array[1][0] = ''steve''; $array[1][1] = ''bob'';

Y me gustaría ser capaz de producir a partir de esta una tabla con todas las combinaciones posibles de estos, pero sin repetir ninguna combinación (independientemente de su posición), por ejemplo, esto produciría

Array 0 Array 1 apples steve apples bob pears steve pears bob

Pero me gustaría que esto funcione con tantas matrices diferentes como sea posible.



foreach($parentArray as $value) { foreach($subArray as $value2) { $comboArray[] = array($value, $value2); } }

No me juzgues ...


function array_comb($arrays) { $result = array(); $arrays = array_values($arrays); $sizeIn = sizeof($arrays); $size = $sizeIn > 0 ? 1 : 0; foreach ($arrays as $array) $size = $size * sizeof($array); for ($i = 0; $i < $size; $i ++) { $result[$i] = array(); for ($j = 0; $j < $sizeIn; $j ++) array_push($result[$i], current($arrays[$j])); for ($j = ($sizeIn -1); $j >= 0; $j --) { if (next($arrays[$j])) break; elseif (isset ($arrays[$j])) reset($arrays[$j]); } } return $result; }


esto se llama "producto cartesiano", página de php man en matrices http://php.net/manual/en/ref.array.php muestra algunas implementaciones (en comentarios).

y aquí hay otra más:

function array_cartesian() { $_ = func_get_args(); if(count($_) == 0) return array(array()); $a = array_shift($_); $c = call_user_func_array(__FUNCTION__, $_); $r = array(); foreach($a as $v) foreach($c as $p) $r[] = array_merge(array($v), $p); return $r; } $cross = array_cartesian( array(''apples'', ''pears'', ''oranges''), array(''steve'', ''bob'') ); print_r($cross);


Esto funciona, creo, aunque después de escribirlo me di cuenta de que es bastante similar a lo que otros han puesto, pero te da una matriz en el formato solicitado. Perdón por los pobres nombres variables.

$output = array(); combinations($array, $output); print_r($output); function combinations ($array, & $output, $index = 0, $p = array()) { foreach ( $array[$index] as $i => $name ) { $copy = $p; $copy[] = $name; $subIndex = $index + 1; if (isset( $array[$subIndex])) { combinations ($array, $output, $subIndex, $copy); } else { foreach ($copy as $index => $name) { if ( !isset($output[$index])) { $output[$index] = array(); } $output[$index][] = $name; } } } }


Syom copió http://www.php.net/manual/en/ref.array.php#54979 pero lo adapté para convertirme en una versión asociativa:

function array_cartesian($arrays) { $result = array(); $keys = array_keys($arrays); $reverse_keys = array_reverse($keys); $size = intval(count($arrays) > 0); foreach ($arrays as $array) { $size *= count($array); } for ($i = 0; $i < $size; $i ++) { $result[$i] = array(); foreach ($keys as $j) { $result[$i][$j] = current($arrays[$j]); } foreach ($reverse_keys as $j) { if (next($arrays[$j])) { break; } elseif (isset ($arrays[$j])) { reset($arrays[$j]); } } } return $result; }


Necesitaba hacer lo mismo y probé las soluciones anteriores publicadas aquí pero no pude hacerlas funcionar. Obtuve una muestra de este tipo inteligente http://www.php.net/manual/en/ref.array.php#54979 . Sin embargo, su muestra no manejó el concepto de ninguna combinación repetitiva. Así que incluí esa parte. Aquí está mi versión modificada, espero que ayude:

$data = array( array(''apples'', ''pears'', ''oranges''), array(''steve'', ''bob'') ); $res_matrix = $this->array_cartesian_product( $data ); foreach ( $res_matrix as $res_array ) { foreach ( $res_array as $res ) { echo $res . " - "; } echo "<br/>"; } function array_cartesian_product( $arrays ) { $result = array(); $arrays = array_values( $arrays ); $sizeIn = sizeof( $arrays ); $size = $sizeIn > 0 ? 1 : 0; foreach ($arrays as $array) $size = $size * sizeof( $array ); $res_index = 0; for ( $i = 0; $i < $size; $i++ ) { $is_duplicate = false; $curr_values = array(); for ( $j = 0; $j < $sizeIn; $j++ ) { $curr = current( $arrays[$j] ); if ( !in_array( $curr, $curr_values ) ) { array_push( $curr_values , $curr ); } else { $is_duplicate = true; break; } } if ( !$is_duplicate ) { $result[ $res_index ] = $curr_values; $res_index++; } for ( $j = ( $sizeIn -1 ); $j >= 0; $j-- ) { $next = next( $arrays[ $j ] ); if ( $next ) { break; } elseif ( isset ( $arrays[ $j ] ) ) { reset( $arrays[ $j ] ); } } } return $result; }

El resultado sería algo como esto:
manzanas - steve
manzanas - bob
peras - steve
peras - bob
naranjas - steve
naranjas - bob

Si la matriz de datos es algo como esto:

$data = array( array(''Amazing'', ''Wonderful''), array(''benefit'', ''offer'', ''reward''), array(''Amazing'', ''Wonderful'') );

Entonces imprimirá algo como esto:

Increíble - beneficio - Maravilloso
Increíble - oferta - Maravilloso
Increíble - recompensa - Maravilloso
Maravilloso - beneficio - increíble
Maravilloso - oferta - increíble
Maravilloso - recompensa - Increíble


@ user187291

Modifiqué esto para ser

function array_cartesian() { $_ = func_get_args(); if (count($_) == 0) return array(); $a = array_shift($_); if (count($_) == 0) $c = array(array()); else $c = call_user_func_array(__FUNCTION__, $_); $r = array(); foreach($a as $v) foreach($c as $p) $r[] = array_merge(array($v), $p); return $r; }

por lo que devuelve esa matriz vacía de suma importancia (el mismo resultado que ninguna combinación) cuando pasa 0 argumentos.

Solo noté esto porque lo estoy usando como

$combos = call_user_func_array(''array_cartesian'', $array_of_arrays);


Tuve que hacer combinaciones de las opciones del producto. Esta solución usa recursión y funciona con matriz 2D:

function options_combinations($options) { $result = array(); if (count($options) <= 1) { $option = array_shift($options); foreach ($option as $value) { $result[] = array($value); } } else { $option = array_shift($options); $next_option = options_combinations($options); foreach ($next_option as $next_value) { foreach ($option as $value) { $result[] = array_merge($next_value, array($value)); } } } return $result; } $options = [[1,2],[3,4,5],[6,7,8,9]]; $c = options_combinations($options); foreach ($c as $combination) { echo implode('' '', $combination)."/n"; }


Implementación elegante basada en la función nativa de Python itertools.product

function direct_product(array ...$arrays) { $result = [[]]; foreach ($arrays as $array) { $tmp = []; foreach ($result as $x) { foreach ($array as $y) { $tmp[] = array_merge($x, [$y]); } } $result = $tmp; } return $result; }