8
votes

Utilisation du chemin de chaîne pour supprimer l'élément de la matrice

J'ai un tableau comme celui-là

    $str = 'baz->foo->boo';
    function array_unset($str, $arr) {

    // magic here

    unset($arr['baz']['foo']['boo']);
    return $arr;
    }


0 commentaires

3 Réponses :


0
votes

quelque chose à la volée qui pourrait fonctionner pour vous:

$str = 'bar,foo,boo';

function array_unset($str,&$arr) {
  $path = explode(',',$str);
  $buf = $arr;
  for($i=0;$i<count($path)-1;$i++) {
    $buf = &$buf[$path[$i]];
  }

  unset($buf);
}


2 commentaires

Ça ne marche pas. À partir du Documentation : Si une variable passée par La référence est non définie () à l'intérieur d'une fonction, seule la variable locale est détruite. La variable dans l'environnement appelant conservera la même valeur qu'avant non défini () a été appelée.


Nope ... cela n'affecte pas $ Arr.



11
votes

Puisque vous ne pouvez pas appeler non définitive sur un élément référencé, vous devez utiliser une autre astuce: xxx

Essence, vous traversez l'arbre de la matrice mais gardez une référence au dernier tableau ( avant-dernière noeud), à partir duquel vous souhaitez supprimer le nœud. Ensuite, vous appelez nonset sur le dernier tableau, passant le dernier nœud comme une touche.

Vérifiez ce codepad


6 commentaires

Bon sang ... c'est intelligent. BTW ont 2 questions. 1) Pourquoi vous utilisez Split? Simple Explorez le travail totalement bien. 2) Pourquoi vous mettez l'argument $ ARR par référence?


1) En utilisant beaucoup de queue de QT / C # dernières semaines, où ils ont tendance à utiliser «Split», explosez simplement de belles idées. 2) Vous devez conserver une référence à la matrice d'origine à tout moment, sinon, non définit ne supprimera que le nœud de la copie au lieu de la matrice d'origine.


Vous pouvez utiliser $ globaux à la place si vous avez le nom de la variable de tableau passée dans le paramètre. (de la DOC: à UNET () une variable globale à l'intérieur d'une fonction, utilisez ensuite le tableau $ Globals pour faire )


@antoox: L'utilisation de $ globales s'attend à ce que votre réseau soit défini à portée mondiale, que j'ai tendance à éviter. Le code de ma réponse est plus portable et peut facilement être adopté pour travailler dans une approche OO.


Mon argument $ ARR a été tiré de l'objet. De toute façon, cela ne peut pas changer de cette fonction ... C'est pourquoi j'ai été confondu de la mettre en référence. À mon avis sur mon établissement et désapprimez Global Varibles Un peu de sorcière de travail supplémentaire ne nécessite pas ici


@Remtsoy Oui, prenez la manipulation qui vous convient. C'est juste une autre méthode.



1
votes

Celui-ci est similaire à Wouter Huystruit. La différence est qu'elle renvoie NULL si vous passez sur un chemin non valide.

function array_unset(&$array, $path)
{
    $pieces = explode('.', $path);
    $i = 0;
    while($i < count($pieces)-1) {
        $piece = $pieces[$i];
        if (!is_array($array) || !array_key_exists($piece, $array)) {
            return null;
        }
        $array = &$array[$piece];
        $i++;
    }
    $piece = end($pieces);
    unset($array[$piece]);
    return $array;
}


0 commentaires