Dividir un array según secuencia

publicado por: Anonymous

Básicamente necesito hacer un split a un array cada vez que encuentre una secuencia de 8 ceros seguidos:

vector base

$vector = [1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0];

El código que modifiqué para realizar la búsqueda de las secuencias de 8 seguidos es:

function BuscarEnVector($vectorBuscar, $vector) 
{
    $listaIndices = array_keys($vector, $vectorBuscar[0]);
    $ret = [];
    
    foreach ($listaIndices as $indice) 
    {
        $adicionar = true;
        $resultado = [];
        
        foreach ($vectorBuscar as $i => $valor) 
        {
            if (!(isset($vector[$indice + $i]) && $vector[$indice + $i] == $valor)) 
            {
                $adicionar = false;
                break;
            }
            
            $resultado[] = $indice + $i;
        }
        
        if ($adicionar == true) 
        { 
            $ret[] = $resultado;
        }            
    }
    
    return $ret;
}

Uso

$vectorCoincidencias = BuscarEnVector([0,0,0,0,0,0,0,0], $vector);

Resultado obtenido:

Array
(
    [0] => Array
        (
            [0] => 3
            [1] => 4
            [2] => 5
            [3] => 6
            [4] => 7
            [5] => 8
            [6] => 9
            [7] => 10
        )

    [1] => Array
        (
            [0] => 14
            [1] => 15
            [2] => 16
            [3] => 17
            [4] => 18
            [5] => 19
            [6] => 20
            [7] => 21
        )

)

Resultado esperado:

del indice 0 al 2 no hay ceros seguidos

del indice 3 al 10 hay 8 ceros seguidos

del indice 11 al 13 no hay ceros seguidos

del indice 14 al 21 hay 8 ceros seguidos

Array
(
    [0] => Array
        (
            [0] => 0
            [1] => 1
            [2] => 2
        )
    [1] => Array
        (
            [0] => 3
            [1] => 4
            [2] => 5
            [3] => 6
            [4] => 7
            [5] => 8
            [6] => 9
            [7] => 10
        )
    [2] => Array
        (
            [0] => 11
            [1] => 12
            [2] => 13
        )        
    [3] => Array
        (
            [0] => 14
            [1] => 15
            [2] => 16
            [3] => 17
            [4] => 18
            [5] => 19
            [6] => 20
            [7] => 21
        )
)

Que debo modificar para tener el resultado esperado?

solución

Aquí dejo una posibilidad. Consiste en una función a la que le pasas un array que se utilizará como separador ($needle) y el array que quieres separar ($array), entonces se ejecuta el siguiente algoritmo:

  1. Convertir los arrays a cadenas de texto
  2. Añadir separadores delante y detrás de la cadena buscada (p.e. usando preg_replace).
  3. Romper la cadena por los separadores (p.e.: usando preg_split que te permite eliminar los elementos vacíos que quedarían si la cadena buscada está al principio y/o al final).
  4. Romper los elementos internos del array en array individuales (p.e. usando str_split).
  5. Devolver el array generado.

Aquí dejo un ejemplo del código:

function separarVector($needle, $array){

    // convertimos los dos arrays en cadenas de texto
    $needle2 = implode("",$needle);
    $array2  = implode("", $array);

    // usamos expresiones regulares para añadir comas delante y detrás de la cadena buscada
    $array2  = preg_replace("/" . $needle2 . "/", "," . $needle2 . ",", $array2);

    // usamos expresiones regulares para convertirlo en un array
    $array2  = preg_split("/,/", $array2, 0, PREG_SPLIT_NO_EMPTY);

    // separa las cadenas internas en arrays
    for($x = 0; $x < count($array2); $x++) {
        $array2[$x] = str_split($array2[$x]);
    }

    // devuelve el array de arrays
    return $array2;

}

$vector  = [0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0];
$vector2 = separarVector([0,0,0,0,0,0,0,0], $vector);
print_r($vector2);

$vector  = [1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0];
$vector2 = separarVector([0,0,0,0,0,0,0,0], $vector);
print_r($vector2);
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *