Error with foreach and cartesian product

0

I have this code:

$CArticulos = Consulta_Dinamica("Array","*","Articulos","'borrado' != 1 ORDER BY 'id' DESC");
    if ($CArticulos) { //si existen Datos en la base de datos

foreach($CArticulos as $DArticulos) {

if (isset($DArticulos['talla'])) { $taLlas = explode(",", $DArticulos['talla']); } else { $tallas=""; }
if (isset($DArticulos['color'])) { $coLores = explode(",", $DArticulos['color']); } else { $colores=""; }

$UpTallicolor = CartesianProduct(array('tallas'=> $taLlas, 'color'=> $coLores));
foreach($UpTallicolor as $DUptallicolor) {
    $CExisteArt = Consulta_Dinamica("Simple","*","Test","'que' = 'Codigo' AND 'idcosa' = '".$DArticulos["id"]."' AND 'Dc1'='".$DUptallicolor['tallas']."' AND 'Dc2'='".$DUptallicolor['color']."' ");
    if ($CExisteArt) { echo "existe"; } else { echo "no existe";
        $CCodEan = Consulta_Dinamica("Simple","*","Configuraciones","'Conf_que' = 'Codigos' AND 'Conf1' = '".$_SESSION['Empresa_Pais']."' ");
        $Eanmin = $CCodEan["Conf2"].$CCodEan["Conf3"].$CCodEan["Conf4"]; $Eanmax = $CCodEan["Conf2"].$CCodEan["Conf3"].$CCodEan["Conf5"];

        $CeanLibre = "SELECT MIN(t1.'Dc3')+1 as prox_ean_libre FROM 'Test' t1 LEFT JOIN 'Test' t2 ON t2.'Dc3'=(t1.'Dc3')+1 AND t2.'Dc3' BETWEEN '".$Eanmin."' AND '".$Eanmax."' WHERE t1.'Dc3' BETWEEN '".$Eanmin."' AND '".$Eanmax."' AND t2.'Dc3' IS NULL"; //miramos de nuevo el ultimo codigo por si aca
        $REanLibre = mysqli_query($Conectar ,$CeanLibre); $DEanLibre=mysqli_fetch_array($REanLibre);
        if (empty($DEanLibre["prox_ean_libre"])) { $Eanlibre = $Eanmin; } else { $Eanlibre = $DEanLibre["prox_ean_libre"]; }
        $UpdTallicolor = Insertar_Datos("Test" , "'que','idcosa','Dc1','Dc2','Dc3'" , "'Codigo','".$DArticulos["id"]."','".$DUptallicolor['tallas']."','".$DUptallicolor['color']."','".$Eanlibre."' "); } //si no existe ese articulo en los codigos
        mysqli_free_result($REanLibre);
} //cierro el foreach

What it does is read the mysql articles table, it generates an array with sizes and another with colors that executes another loop with a cartesian product to assign ean codes to each cartesian product, in which I look at what is previously free. The fact is that if you have few records, it works fine, but at the moment there are enough (about 100) it is slow to the point that it gives a waiting time error and does not save anything.

Is there a way to optimize it or make it run bit by bit (with each loop you save in mysql)?

the code to generate the Cartesian product is this:

function CartesianProduct($sets) {
    $cartesian = array();
    foreach ($sets as $key => $set) { if (empty($set)) { continue; } // Si un grupo esta vació no afecta el producto cartesiano
    if (empty($cartesian)) { $cartesian[] = array(); }// Si esta vacio agregamos el primer grupo
    $subset = array();
    foreach ($cartesian as $product) {
        foreach($set as $value) {
            $product[$key] = $value;
            $subset[] = $product;
        }
    }
$cartesian = $subset;
    }
return $cartesian;
}

the array that the cartesian product of a single article generates is this:

Array ( [0] => Array ( [tallas] => 60 [color] => 250 ) [1] => Array ( [tallas] => 60 [color] => 252 ) [2] => Array ( [tallas] => 60 [color] => 185 ) [3] => Array ( [tallas] => 60 [color] => 158 ) [4] => Array ( [tallas] => 60 [color] => 183 ) [5] => Array ( [tallas] => 60 [color] => 106 ) [6] => Array ( [tallas] => 60 [color] => 198 ) [7] => Array ( [tallas] => 60 [color] => 181 ) [8] => Array ( [tallas] => 60 [color] => 72 ) [9] => Array ( [tallas] => 60 [color] => 178 ) [10] => Array ( [tallas] => 60 [color] => 184 ) [11] => Array ( [tallas] => 60 [color] => 180 ) [12] => Array ( [tallas] => 60 [color] => 196 ) [13] => Array ( [tallas] => 60 [color] => 147 ) [14] => Array ( [tallas] => 60 [color] => 116 ) [15] => Array ( [tallas] => 60 [color] => 166 ) [16] => Array ( [tallas] => 60 [color] => 165 ) [17] => Array ( [tallas] => 60 [color] => 179 ) [18] => Array ( [tallas] => 60 [color] => 151 ) [19] => Array ( [tallas] => 60 [color] => 197 ) [20] => Array ( [tallas] => 60 [color] => 195 ) [21] => Array ( [tallas] => 60 [color] => 177 ) [22] => Array ( [tallas] => 61 [color] => 250 ) [23] => Array ( [tallas] => 61 [color] => 252 ) [24] => Array ( [tallas] => 61 [color] => 185 ) [25] => Array ( [tallas] => 61 [color] => 158 ) [26] => Array ( [tallas] => 61 [color] => 183 ) [27] => Array ( [tallas] => 61 [color] => 106 ) [28] => Array ( [tallas] => 61 [color] => 198 ) [29] => Array ( [tallas] => 61 [color] => 181 ) [30] => Array ( [tallas] => 61 [color] => 72 ) [31] => Array ( [tallas] => 61 [color] => 178 ) [32] => Array ( [tallas] => 61 [color] => 184 ) [33] => Array ( [tallas] => 61 [color] => 180 ) [34] => Array ( [tallas] => 61 [color] => 196 ) [35] => Array ( [tallas] => 61 [color] => 147 ) [36] => Array ( [tallas] => 61 [color] => 116 ) [37] => Array ( [tallas] => 61 [color] => 166 ) [38] => Array ( [tallas] => 61 [color] => 165 ) [39] => Array ( [tallas] => 61 [color] => 179 ) [40] => Array ( [tallas] => 61 [color] => 151 ) [41] => Array ( [tallas] => 61 [color] => 197 ) [42] => Array ( [tallas] => 61 [color] => 195 ) [43] => Array ( [tallas] => 61 [color] => 177 ) [44] => Array ( [tallas] => 62 [color] => 250 ) [45] => Array ( [tallas] => 62 [color] => 252 ) [46] => Array ( [tallas] => 62 [color] => 185 ) [47] => Array ( [tallas] => 62 [color] => 158 ) [48] => Array ( [tallas] => 62 [color] => 183 ) [49] => Array ( [tallas] => 62 [color] => 106 ) [50] => Array ( [tallas] => 62 [color] => 198 ) [51] => Array ( [tallas] => 62 [color] => 181 ) [52] => Array ( [tallas] => 62 [color] => 72 ) [53] => Array ( [tallas] => 62 [color] => 178 ) [54] => Array ( [tallas] => 62 [color] => 184 ) [55] => Array ( [tallas] => 62 [color] => 180 ) [56] => Array ( [tallas] => 62 [color] => 196 ) [57] => Array ( [tallas] => 62 [color] => 147 ) [58] => Array ( [tallas] => 62 [color] => 116 ) [59] => Array ( [tallas] => 62 [color] => 166 ) [60] => Array ( [tallas] => 62 [color] => 165 ) [61] => Array ( [tallas] => 62 [color] => 179 ) [62] => Array ( [tallas] => 62 [color] => 151 ) [63] => Array ( [tallas] => 62 [color] => 197 ) [64] => Array ( [tallas] => 62 [color] => 195 ) [65] => Array ( [tallas] => 62 [color] => 177 ) [66] => Array ( [tallas] => 63 [color] => 250 ) [67] => Array ( [tallas] => 63 [color] => 252 ) [68] => Array ( [tallas] => 63 [color] => 185 ) [69] => Array ( [tallas] => 63 [color] => 158 ) [70] => Array ( [tallas] => 63 [color] => 183 ) [71] => Array ( [tallas] => 63 [color] => 106 ) [72] => Array ( [tallas] => 63 [color] => 198 ) [73] => Array ( [tallas] => 63 [color] => 181 ) [74] => Array ( [tallas] => 63 [color] => 72 ) [75] => Array ( [tallas] => 63 [color] => 178 ) [76] => Array ( [tallas] => 63 [color] => 184 ) [77] => Array ( [tallas] => 63 [color] => 180 ) [78] => Array ( [tallas] => 63 [color] => 196 ) [79] => Array ( [tallas] => 63 [color] => 147 ) [80] => Array ( [tallas] => 63 [color] => 116 ) [81] => Array ( [tallas] => 63 [color] => 166 ) [82] => Array ( [tallas] => 63 [color] => 165 ) [83] => Array ( [tallas] => 63 [color] => 179 ) [84] => Array ( [tallas] => 63 [color] => 151 ) [85] => Array ( [tallas] => 63 [color] => 197 ) [86] => Array ( [tallas] => 63 [color] => 195 ) [87] => Array ( [tallas] => 63 [color] => 177 ) [88] => Array ( [tallas] => 64 [color] => 250 ) [89] => Array ( [tallas] => 64 [color] => 252 ) [90] => Array ( [tallas] => 64 [color] => 185 ) [91] => Array ( [tallas] => 64 [color] => 158 ) [92] => Array ( [tallas] => 64 [color] => 183 ) [93] => Array ( [tallas] => 64 [color] => 106 ) [94] => Array ( [tallas] => 64 [color] => 198 ) [95] => Array ( [tallas] => 64 [color] => 181 ) [96] => Array ( [tallas] => 64 [color] => 72 ) [97] => Array ( [tallas] => 64 [color] => 178 ) [98] => Array ( [tallas] => 64 [color] => 184 ) [99] => Array ( [tallas] => 64 [color] => 180 ) [100] => Array ( [tallas] => 64 [color] => 196 ) [101] => Array ( [tallas] => 64 [color] => 147 ) [102] => Array ( [tallas] => 64 [color] => 116 ) [103] => Array ( [tallas] => 64 [color] => 166 ) [104] => Array ( [tallas] => 64 [color] => 165 ) [105] => Array ( [tallas] => 64 [color] => 179 ) [106] => Array ( [tallas] => 64 [color] => 151 ) [107] => Array ( [tallas] => 64 [color] => 197 ) [108] => Array ( [tallas] => 64 [color] => 195 ) [109] => Array ( [tallas] => 64 [color] => 177 ) [110] => Array ( [tallas] => 65 [color] => 250 ) [111] => Array ( [tallas] => 65 [color] => 252 ) [112] => Array ( [tallas] => 65 [color] => 185 ) [113] => Array ( [tallas] => 65 [color] => 158 ) [114] => Array ( [tallas] => 65 [color] => 183 ) [115] => Array ( [tallas] => 65 [color] => 106 ) [116] => Array ( [tallas] => 65 [color] => 198 ) [117] => Array ( [tallas] => 65 [color] => 181 ) [118] => Array ( [tallas] => 65 [color] => 72 ) [119] => Array ( [tallas] => 65 [color] => 178 ) [120] => Array ( [tallas] => 65 [color] => 184 ) [121] => Array ( [tallas] => 65 [color] => 180 ) [122] => Array ( [tallas] => 65 [color] => 196 ) [123] => Array ( [tallas] => 65 [color] => 147 ) [124] => Array ( [tallas] => 65 [color] => 116 ) [125] => Array ( [tallas] => 65 [color] => 166 ) [126] => Array ( [tallas] => 65 [color] => 165 ) [127] => Array ( [tallas] => 65 [color] => 179 ) [128] => Array ( [tallas] => 65 [color] => 151 ) [129] => Array ( [tallas] => 65 [color] => 197 ) [130] => Array ( [tallas] => 65 [color] => 195 ) [131] => Array ( [tallas] => 65 [color] => 177 ) [132] => Array ( [tallas] => 66 [color] => 250 ) [133] => Array ( [tallas] => 66 [color] => 252 ) [134] => Array ( [tallas] => 66 [color] => 185 ) [135] => Array ( [tallas] => 66 [color] => 158 ) [136] => Array ( [tallas] => 66 [color] => 183 ) [137] => Array ( [tallas] => 66 [color] => 106 ) [138] => Array ( [tallas] => 66 [color] => 198 ) [139] => Array ( [tallas] => 66 [color] => 181 ) [140] => Array ( [tallas] => 66 [color] => 72 ) [141] => Array ( [tallas] => 66 [color] => 178 ) [142] => Array ( [tallas] => 66 [color] => 184 ) [143] => Array ( [tallas] => 66 [color] => 180 ) [144] => Array ( [tallas] => 66 [color] => 196 ) [145] => Array ( [tallas] => 66 [color] => 147 ) [146] => Array ( [tallas] => 66 [color] => 116 ) [147] => Array ( [tallas] => 66 [color] => 166 ) [148] => Array ( [tallas] => 66 [color] => 165 ) [149] => Array ( [tallas] => 66 [color] => 179 ) [150] => Array ( [tallas] => 66 [color] => 151 ) [151] => Array ( [tallas] => 66 [color] => 197 ) [152] => Array ( [tallas] => 66 [color] => 195 ) [153] => Array ( [tallas] => 66 [color] => 177 ) [154] => Array ( [tallas] => 67 [color] => 250 ) [155] => Array ( [tallas] => 67 [color] => 252 ) [156] => Array ( [tallas] => 67 [color] => 185 ) [157] => Array ( [tallas] => 67 [color] => 158 ) [158] => Array ( [tallas] => 67 [color] => 183 ) [159] => Array ( [tallas] => 67 [color] => 106 ) [160] => Array ( [tallas] => 67 [color] => 198 ) [161] => Array ( [tallas] => 67 [color] => 181 ) [162] => Array ( [tallas] => 67 [color] => 72 ) [163] => Array ( [tallas] => 67 [color] => 178 ) [164] => Array ( [tallas] => 67 [color] => 184 ) [165] => Array ( [tallas] => 67 [color] => 180 ) [166] => Array ( [tallas] => 67 [color] => 196 ) [167] => Array ( [tallas] => 67 [color] => 147 ) [168] => Array ( [tallas] => 67 [color] => 116 ) [169] => Array ( [tallas] => 67 [color] => 166 ) [170] => Array ( [tallas] => 67 [color] => 165 ) [171] => Array ( [tallas] => 67 [color] => 179 ) [172] => Array ( [tallas] => 67 [color] => 151 ) [173] => Array ( [tallas] => 67 [color] => 197 ) [174] => Array ( [tallas] => 67 [color] => 195 ) [175] => Array ( [tallas] => 67 [color] => 177 ) )

the array that generates the response code is this:

Array ( [0] => Array ( [tallas] => 60 ) [1] => Array ( [tallas] => 61 ) [2] => Array ( [tallas] => 62 ) [3] => Array ( [tallas] => 63 ) [4] => Array ( [tallas] => 64 ) [5] => Array ( [tallas] => 65 ) [6] => Array ( [tallas] => 66 ) [7] => Array ( [tallas] => 67 ) [8] => Array ( [tallas] => 67 [color] => 250 ) [9] => Array ( [tallas] => 67 [color] => 252 ) [10] => Array ( [tallas] => 67 [color] => 185 ) [11] => Array ( [tallas] => 67 [color] => 158 ) [12] => Array ( [tallas] => 67 [color] => 183 ) [13] => Array ( [tallas] => 67 [color] => 106 ) [14] => Array ( [tallas] => 67 [color] => 198 ) [15] => Array ( [tallas] => 67 [color] => 181 ) [16] => Array ( [tallas] => 67 [color] => 72 ) [17] => Array ( [tallas] => 67 [color] => 178 ) [18] => Array ( [tallas] => 67 [color] => 184 ) [19] => Array ( [tallas] => 67 [color] => 180 ) [20] => Array ( [tallas] => 67 [color] => 196 ) [21] => Array ( [tallas] => 67 [color] => 147 ) [22] => Array ( [tallas] => 67 [color] => 116 ) [23] => Array ( [tallas] => 67 [color] => 166 ) [24] => Array ( [tallas] => 67 [color] => 165 ) [25] => Array ( [tallas] => 67 [color] => 179 ) [26] => Array ( [tallas] => 67 [color] => 151 ) [27] => Array ( [tallas] => 67 [color] => 197 ) [28] => Array ( [tallas] => 67 [color] => 195 ) [29] => Array ( [tallas] => 67 [color] => 177 ) ) 
    
asked by Killpe 15.10.2017 в 22:49
source

1 answer

1

I was looking more closely at your code. You may have multiple errors in the logic of the program, and without getting into BD design.

Try changing your CartesianProduct function for this one at the moment, to see if it keeps working:

function CartesianProduct( $arr_sets ) {

    if ( ! $arr_sets || ! is_array( $arr_sets ))
        return FALSE;


    $product   = array();
    $cartesian = array();
    foreach ( $arr_sets as $key => $set ) {

        if ( $set && is_array( $set )) { 

            foreach( $set as $value ) {

                $product[ $key ] = $value;
                $cartesian[] = $product;
            }
        }
    }


    return $cartesian;
}

** ==================

I add content: **

It is smaller and changes the way of interpreting it, what I do not know if he has all the data. I can not prove it. Tea explain in steps what changes.

/*** Código original ***/
function CartesianProduct( $arr_sets ) {

    $cartesian = array();
    foreach ( $arr_sets as $key => $set ) { 

        if ( empty( $set )) { 
            continue; 
        } // Si un grupo esta vació no afecta el producto cartesiano

        if ( empty( $cartesian )) { 
            $cartesian[] = array(); 
        }// Si esta vacio agregamos el primer grupo

        $subset = array();
        foreach ( $cartesian as $product ) {

            foreach( $set as $value ) {

                $product[ $key ] = $value;
                $subset[] = $product;
            }
        }

        $cartesian = $subset;
    }

    return $cartesian;
}


/**
 * 1. Esto generaría el mismo array que tu código
 * 
 * Inicializo todos los arrays que vamos a utilizar fuera del foreach principal
 * Elimino tus dos primeros bloques condicionales:
 *   "if (empty($set)) { continue; }" lo sustituyo incluyendo todo en el condicional:
 *   "if ( $set && is_array( $set )) { ... }" incluyendo el código subsiguiente 
 *   dentro "if (empty($cartesian)) { $cartesian[] = array(); }" lo sustituyo por 
 *   
 *   "$cartesian[] = array();" antes del foreach, entiendo que esto se hace en
 *   la primera iteración del foreach porque $cartesian, recien declarado es un 
 *   array vacio siempre
 * 
 */
function CartesianProduct( $arr_sets ) {

    if ( ! $arr_sets || ! is_array( $arr_sets ))
        return FALSE;

    $cartesian = array();
    $subset    = array();
    $cartesian[] = array();
    foreach ($arr_sets as $key => $set) {

        if ( $set && is_array( $set )) {

            foreach ($cartesian as $product) {

                foreach($set as $value) {

                    $product[$key] = $value;
                    $subset[] = $product;
                }
            }

            $cartesian = $subset; 
        }
    }


    return $cartesian;
}

/**
 * 2. Mismo código, con una clausula de salvaguarda al comienzo y comentarios. La salida debería seguir siendo la misma que tienes
 * 
 */
function CartesianProduct( $arr_sets ) {

    /**
     * Clausula de salvaguarda
     * 
     * Evita error si la función no recibe un array y que se siga ejecutando 
     * el resto del código, evitando añadir un nivel de indentado
     */
    if ( ! $arr_sets || ! is_array( $arr_sets ))
        return FALSE;

    /**
     * Inicializa los arrays que se usarán
     *
     */
    $cartesian = array();
    $subset    = array();
    $cartesian[] = array();
    foreach ( $arr_sets as $key => $set ) {

        //Este condicional actua como la clausula de salvaguarda, pero no
        //finaliza la ejcución ni evita un nivel de indentado, incluye todo 
        //lo que se va a enecutar en la interacción en su interior
        if ( $set && is_array( $set )) {

            foreach ($cartesian as $product) {

                foreach($set as $value) {

                    $product[$key] = $value;
                    $subset[] = $product;
                }
            }

            $cartesian = $subset; 
        }
    }


    return $cartesian;
}

/**
 * 3. Simplificando. Esto cambia la salida
 * 
 * Pongo sólo la parte de código que queda por cambiar
 */
$cartesian = array();
$subset    = array();
//$cartesian[] = array();
foreach ( $arr_sets as $key => $set ) {

    //Este condicional actua como la clausula de salvaguarda, pero no
    //finaliza la ejcución ni evita un nivel de indentado, incluye todo 
    //lo que se va a enecutar en la interacción en su interior
    if ( $set && is_array( $set )) {

        /**
         * Este foreach sobra, se debería ejecutar una sola vez, solo 
         * tiene un array vacio en la primera posición
         * 
         * Una declaración previa de "$product = array();" reemplazaría 
         * a "$cartesian[] = array();" y permite eliminar este "foreach"
         */
        //foreach ($cartesian as $product) {

            foreach( $set as $value ) {

                $product[ $key ] = $value;
                $subset[] = $product;
            }
        //}

        $cartesian = $subset; 
    }
}

/**
 * 4. Simplificando. Esto cambia la salida
 * 
 * Pongo sólo la parte de código que queda por cambiar
 * 
 * El array "subset" ya no es necesario, empleo a "cartesian" en su lugar
 */
$cartesian = array();
$product   = array();
foreach ( $arr_sets as $key => $set ) {

    if ( $set && is_array( $set )) {

        foreach( $set as $value ) {

            $product[ $key ] = $value;
            $cartesian[] = $product;
        }
    }
}
    
answered by 16.10.2017 в 11:58