4
votes

Bogue de la fonction récursive PHP?

J'ai créé cette fonction pour rechercher dans un tableau imbriqué mais je continue à obtenir null pour ce tableau:

$arr3 = [
    'first' => 1,
    'second' => 2,
    'third' => [
        'fourth' => 4,
    ]
];

/**
 * returns the key for the first found value
 *
 * @param $needle
 * @param array $haystack
 * @return false|int|string
 */
function array_search_value($needle, array $haystack) {

    $result = null;
    $found = array_search($needle, $haystack);

    if ( $found !== false ) {
        // end the recursion
        $result = $found;

    } else {
        foreach ($haystack as $key => $item) {
            if (is_array($item)) {
                array_search_value($needle, $item);
            } else {
                continue;
            }
        }
    }

    return $result;
}

var_dump(array_search_value(4, $arr3));

Je ne peux pas comprendre ce que j'ai fait de mal? Le résultat var_dump () doit être une chaîne "quatrième" .


3 commentaires

Dans la boucle for, vous devez attribuer le résultat à l'appel récursif


Lorsque vous appelez une fonction de manière récursive, vous devez vous assurer de propager la valeur de retour de l'appel récursif à l'appelant d'origine: return array_search_value ($ aiguille, $ item);


Oui ... vous aviez raison ... la déclaration de retour manquait dans l'appel récursif ... S'il vous plaît, quelqu'un réponds pour que je puisse l'accepter.


5 Réponses :


1
votes

Renvoyez simplement l'appel récursif de la fonction array_search_value :

    $arr3 = [
    'first' => 1,
    'second' => 2,
    'third' => [
        'fourth' => 4,
    ]
];

/**
 * returns the key for the first found value
 *
 * @param $needle
 * @param array $haystack
 * @return false|int|string
 */
function array_search_value($needle, array $haystack) {

    $result = null;
    $found = array_search($needle, $haystack);

    if ( $found !== false ) {
        // end the recursion
        $result = $found;

    } else {
        foreach ($haystack as $key => $item) {
            if (is_array($item)) {
                return array_search_value($needle, $item);
            } else {
                continue;
            }
        }
    }

    return $result;
}

var_dump(array_search_value(4, $arr3));


3 commentaires

Pas bien! Que faire si le premier tableau n'a pas la valeur mais le second a ??


Il ira récursivement jusqu'à ce qu'il fonde quelque chose ... et s'il n'y a rien, il retournera null


votre question est une bonne base au cas où il y aurait plus d'un tableau en profondeur



1
votes

Lorsque vous appelez une fonction de manière récursive, vous devez vous assurer de propager la valeur de retour de l'appel récursif à l'appelant d'origine:

    $arr3 = [
    'first' => 1,
    'second' => 2,
    'third' => [
        'fourth' => 4,
    ]
];

/**
 * returns the key for the first found value
 *
 * @param $needle
 * @param array $haystack
 * @return false|int|string
 */
function array_search_value($needle, array $haystack) {

    $result = null;
    $found = array_search($needle, $haystack);

    if ( $found !== false ) {
        // end the recursion
        $result = $found;

    } else {

        foreach ($haystack as $key => $item) {
            if (is_array($item)) { 
               $target = array_search_value($needle, $item);
                if ($target){
                    return $target;
                }
            } else {
                continue;
            }
        }

    }
    return $result;
}

var_dump(array_search_value(4, $arr3));


1 commentaires

Pas bien! Que faire si le premier tableau n'a pas la valeur mais le second a ??



2
votes

Il vous manque l'attribution de l'appel récursif $ result . Vous devez changer:

if (is_array($item) ) {
    $i = array_search_value($needle, $item);
    if ($i)
        return $i;

En: (notez que c'est la valeur introuvable, continuez la recherche et pas seulement retournez)

if (is_array($item)) {
     array_search_value($needle, $item);


3 commentaires

il suffit d'écrire return array_search_value ($ aiguille, $ item); !


Essayez le cas où $ arr = ["a" => ["b" => 1], "c" => ["d" => 4]] et recherchez 4 < / code>


Heureux de vous aider. Notez la réponse @apokryfos qui est également bonne - mais je ne sais pas ce dont vous avez besoin, alors choisissez simplement votre sortie



3
votes

Si vous trouvez ce que vous cherchez pendant la récursion, vous ne le stockez pas vraiment n'importe où. Voici mon approche recommandée:

function array_search_value_all($needle, array $haystack) {

    $result = [];
    $found = array_search($needle, $haystack);

    if ( $found !== false ) {
        // end the recursion
        $result[] = [ $found ]; //Array will make sense in a bit

    } else {
        foreach ($haystack as $key => $item) {
            if (is_array($item)) {
                $found = array_search_value($needle, $item);
                if ($found !== []) {
                   $result[] = array_merge([$key],$found);
                }
            } else {
                continue;
            }
        }
    }

    return $result;
}

La raison du renvoi d'un tableau est au cas où le sous-tableau a la même clé que le tableau principal afin que vous puissiez toujours récupérer la clé correcte en accédant de manière récursive au index de tableau pour chaque entrée de tableau renvoyée.

Consultez le code sur: http://sandbox.onlinephpfunctions.com/code / 085c949f660504010ed7ebb7a846e31b3a766d61

Voici un exemple des raisons pour lesquelles le retour d'un tableau peut être nécessaire:

Si vous considérez le tableau:

$arr3 = [
    'a' => 1,
    'b' => 2,
    'c' => [
        'a' => 4,
    ],
    "d"=>[
        "a" => [
            "a" => 19    
        ]
    ]
];


6 commentaires

Quelque chose ne va pas avec votre solution ... J'obtiens un tableau avec 2 valeurs: array (size = 2) 0 => string 'third' (length = 5) 1 => string 'quatrième' (length = 6)


Je suppose que c'est bien - il voulait renvoyer le chemin complet et pas seulement la sous-clé. Nice one @apokryfos. Même si ce n'est pas ce que signifiait l'OP :)


@dWinder en fait dans cette réponse, vous obtiendrez le premier chemin qui mène à 4. Si vous voulez obtenir tous les chemins menant à 4, ce serait encore plus compliqué. J'essaierai de proposer une alternative qui pourrait tout


avec apokryfs answer, vous pouvez utiliser le résultat pour obtenir la valeur directement à partir de ce tableau imbriqué. par exemple j'obtiens le ['c', 'd'] et puis il peut être utilisé pour obtenir cette valeur par programme


Je viens de réaliser que j'ai supprimé mon commentaire


Pas nécessaire pour tout obtenir, ce serait une question complètement différente.



0
votes
    $arr3 = [
    'first' => 1,
    'second' => 2,
    'third' => [
        'fourth' => 4,
    ]
];

/**
 * returns the key for the first found value
 *
 * @param $needle
 * @param array $haystack
 * @return false|int|string
 */
function array_search_value($needle, array $haystack) {

    $found = array_search($needle, $haystack);

    if ($found) {
        // put directly return here
        return $found;

    } else {
        foreach ($haystack as $key => $item) {
            if (is_array($item)) {
                return array_search_value($needle, $item);
            } else {
                continue;
            }
        }
    }

}

2 commentaires

Qu'ajoutez-vous en plus des réponses existantes?


Peut-être, mais ce n'est pas une réponse au problème OP