Probar si una matriz es un subconjunto de otra

5 minutos de lectura

Avatar de usuario de Kamesh Jungi
Kamesh Jungi

¿Cómo puedo determinar si una matriz es un subconjunto de otra (todos los elementos de la primera están presentes en la segunda)?

 $s1 = "string1>string2>string3>string4>string5>string6>";
 $arr1 = explode(">", $s1);
 $s2 = "string1>string4>string5";
 $arr2 = explode(">", $s2);

 $isSubset = /* ??? */

if (array_intersect($array1, $array2) == $array1) {
    // $array1 is a subset of $array2
}

  • array_intersect :), buena solución

    – Shail

    5 de septiembre de 2012 a las 7:48

  • Sin embargo, el tuyo es mejor. 🙂

    – deceze

    5 de septiembre de 2012 a las 7:50

  • @Tamas Bueno, no, array_diff en realidad es mucho más elegante. 🙂

    – deceze

    5 de agosto de 2013 a las 12:20

  • array_diff([‘a’, ‘b’, ‘c’], [‘a’, ‘b’]) volverá [‘c’]. Sin embargo, array_diff([‘c’], [‘d’]) también volverá [‘c’] así que en realidad no es una solución tan elegante.

    – aleemb

    22 de junio de 2015 a las 0:40

  • @aleemb Bueno… si array_diff da como resultado cualquier cosa menos una matriz vacía, la matriz es no un subconjunto del otro. Si el resultado es una matriz vacía, es un subconjunto. Entonces, los resultados en su ejemplo son esperados y correctos y exactamente lo que queremos.

    – deceze

    22 de junio de 2015 a las 7:17

avatar de usuario de shail
Shail

Simple: usa la resta de matrices.

En la resta de matrices, sabrá si una matriz es o no un subconjunto de la otra.

Ejemplo:

if (!array_diff($array1, $array2)) {
    // $array1 is a subset of $array2
}

Referencia: array_diff

Puedes usar array_intersect también.

Trata eso

  • array_diff([‘a’, ‘b’, ‘c’], [‘a’, ‘b’]) volverá [‘c’]. Sin embargo, array_diff([‘c’], [‘d’]) también volverá [‘c’] así que en realidad no es una solución tan elegante.

    – aleemb

    22 de junio de 2015 a las 0:40

  • array_diff_assoc es más seguro al comparar matrices multidimensionales si tiene tipos específicos para cada clave en la matriz

    – Tez

    6 de diciembre de 2017 a las 23:14

  • @aleemb No veo tu punto. Para esta solución: array_diff(['a', 'b','c'], ['a', 'b']) devoluciones ['c']lo que significa que array1 no es un subconjunto de array2 –> correcto. array_diff(['c'], ['d']) devoluciones ['c'], lo que significa que array1 no es un subconjunto de array2 –> correcto. ¿Lo que está mal?

    – aluminio

    12 de julio de 2018 a las 15:06


  • Creo que un problema es que es difícil pensar en esta solución. array_intersect la solución no tiene negación y no involucra matemáticas. Es fácil de visualizar mentalmente.

    – chamán de datos

    11 de diciembre de 2019 a las 15:37


  • Pero array_diff convierte ambos en cadenas, por lo que si tiene dos matrices de objetos, obtendrá el error “el objeto de la clase _____ no se pudo convertir en una cadena”.

    – Alguien_a quien_le gusta_SE

    30 de diciembre de 2021 a las 0:45

Avatar de usuario de Elias Van Ootegem
Elias Van Ootegem

Si comienza desde cadenas, puede verificar strstr($fullString,$subsetStr);. Pero eso solo funcionará cuando todos los caracteres tengan el mismo orden: 'abcd','cd' funcionará, pero 'abcd','ad' no.

Pero en lugar de escribir su propia función personalizada, debe saber que PHP tiene MONTONES de funciones de matriz, por lo que es casi imposible que no haya una función estándar que pueda hacer lo que necesita que haga. En este caso, sugeriría array_diff:

$srcString = explode('>','string1>string2>string3>string4>string5');
$subset = explode('>','string3>string2>string5');
$isSubset = array_diff($subset,$srcString);
//if (empty($isSubset)) --> cf comments: somewhat safer branch:
if (!$isSubset)
{
    echo 'Subset';
    return true;
}
else
{
    echo 'Nope, substrings: '.implode(', ',$isSubset).' Didn\'t match';
    return false;
}

  • Por favor mira La guía definitiva para isset y vacío de PHP por que no.

    – deceze

    5 de septiembre de 2012 a las 7:59

  • Gracias, pero como dice: no hay una diferencia real aquí: empty === suelta la comparación con falseentonces empty($var) y !$var son intercambiables. El único beneficio AFAIK, es que !$var arroja errores cuando $var es indefinido. Esto no es posible en el fragmento anterior. Sin embargo, editaré mi respuesta, en caso de que alguien, por cualquier motivo, decida agregar numerosas líneas de código entre el array_diff y if()

    – Elías Van Ootegem

    5 de septiembre de 2012 a las 8:07

  • Bueno, exactamente. Deberías usar empty sólo para variables que puede legítimamente no existir. De lo contrario, está renunciando innecesariamente a las ventajas del informe de errores de PHP. Es solo una regla general que debe seguir para hacer su propia vida más fácil al no suprimir los informes de errores.

    – deceze

    5 de septiembre de 2012 a las 8:09

  • No me importa que me voten negativo, pero me importa que la gente no se moleste en explicar por qué

    – Elías Van Ootegem

    19 de diciembre de 2013 a las 7:21

  • $isSubset debería llamarse $isntSubset, ¿no?

    – Dan Chadwick

    29 ago 2018 a las 14:00

avatar de usuario de ajon
ajon

Crearía una matriz asociada de la matriz más grande, luego iteraría a través de la matriz más pequeña, buscando una no colisión, si encuentra una, devuelva falso.

function isSubset($arr1,$arr2){
    $map = Array();
    for ($i=0;$i<count($arr1);$i++){
      $map[$arr[$i]]=true;
    }
    for ($i=0;$i<count($arr2);$i++){
       if (!isset($map[$arr2[$i]])){
          return false;
       }
    }
    return true;

avatar de usuario de lobo
lobo

$s1 = "1>2>3>4>5>6>7";

$arr1 = explode(">",$s1);

$s2 = "1>2>3";

$arr2 = explode(">",$s2); 

if(isSub($arr1,$arr2)){

         echo 'true';

}else{

         echo 'false';
}

function isSub($a1,$a2){

    $num2 = count($a2);
    $sub  = $num2;

    for($i = 0;$i < $num2 ;$i++){
        if(in_array($a2[$i],$a1)){
            $sub--;
        }
    }
    return ($sub==0)? true:false;
}

avatar de usuario de jeetu
jeetu

Función simple que devolverá verdadero si la matriz es un subconjunto exacto; de lo contrario, será falso. La solución también es aplicable para matrices bidimensionales.

 function is_array_subset($superArr, $subArr) {
        foreach ($subArr as $key => $value) {
            //check if keys not set in super array OR values are unequal in both array.
            if (!isset($superArr[$key]) || $superArr[$key] != $value) {
                return false;
            }
        }
        return true;
    }

¿Ha sido útil esta solución?