2010-09-01 5 views
2

Considérons un simple ArrayObject PHP avec deux éléments.Réinitialiser la valeur de pointeur interne d'un tableau PHP (ArrayObject)

$ao = new ArrayObject(); 
$ao[] = 'a1'; // [0] => a1 
$ao[] = 'a2'; // [1] => a2 

Ensuite, supprimez le dernier élément et ajoutez un nouvel élément. J'aimerais beaucoup avoir 'a3' be [1].

Comment puis-je réinitialiser la valeur du pointeur interne avant J'ai ajouté 'a3'?

J'ai une fonction simple qui fait cela mais je préfère ne pas copier le tableau si je n'ai pas à le faire.

function array_collapse($array) { 
    $return = array(); 
    while ($a = current($array)) { 
     $return[] = $a; 
     next($array); 
    } 
    return $return; 
} 
+0

Il me semble que mon exemple est seulement l'un des scénarios d'utilisation d'un couple que je rencontre. Pour la question, je vais le laisser intact mais aussi ajouter ... Si le ou les éléments du tableau à supprimer ne sont pas le dernier élément (s) alors un effondrement est nécessaire avant de réinitialiser le pointeur interne. Est-il possible d'avoir un tableau de quatre éléments ([0], [1], [2] et [3]), supprimer [1] et [2], et réinitialiser le pointeur pour que l'élément suivant soit ajouté [2]? – allnightgrocery

Répondre

2

Avec l'expansion sur la question dans vos commentaires: vous auriez à étendre la classe ArrayObject pour obtenir ce genre de comportement:

class ReindexingArray extends ArrayObject { 
    function offsetUnset($offset){ 
     parent::offsetUnset($offset); 
     $this->exchangeArray(array_values($this->getArrayCopy())); 
    } 
    //repeat for every other function altering the values. 
} 

Une autre option serait la SplDoublyLinkedList:

<?php 
$u = new SplDoublyLinkedList(); 
$array = array('1' => 'one', 
       '2' => 'two', 
       '3' => 'three'); 
foreach($array as $value) $u[] = $value; 
var_dump($u); 
unset($u[1]);   
var_dump($u); 
$u[] = 'another thing'; 
var_dump($u); 
+0

Est-ce toujours la meilleure réponse aujourd'hui? J'ai le même problème et je suis inquiet de l'impact sur les performances de la ligne $ this-> exchangeArray (array_values ​​(...)) – Flion

+0

La meilleure réponse est de ne pas se soucier du nombre de vos clés. Pensez-y d'abord: pourquoi auriez-vous besoin de ce dont le PO a besoin? – Wrikken

+0

bien je devais faire une boucle sur les membres de l'ArrayObject et en supprimer quelques uns. Pour éviter cela, je suis passé par les clés supposées du plus haut au plus bas. Mais d'accord: ne pas avoir besoin de connaître les clés est la bonne solution, et j'ai déjà réécrit le code en utilisant getArrayCopy() – Flion

0

Pourquoi ne pas utiliser offsetSet:

$ao = new ArrayObject(); 
$ao[] = 'a1'; // [0] => a1 
$ao[] = 'a2'; // [1] => a2 
$ao->offsetUnset(1); 
$ao->offsetSet(1, 'a3'); 
+0

Bon point. Ma question a manqué quelques détails qui sont très importants. Je vous remercie. – allnightgrocery

0

C'est un peu boiteux, mais vous pouvez jeter à un tableau standard et utiliser array_splice dessus:

$ao = new ArrayObject(); 
$ao[] = 'element 1'; 
$ao[] = 'element 2'; 
$ao[] = 'element 3'; 
$ao[] = 'element 4'; 

var_dump($ao); 

$items = (array) $ao; 
array_splice($items, 1, 2); 
$ao = new ArrayObject($items); 
$ao[] = 'element 5'; 

var_dump($ao); 

Il en résulte:

object(ArrayObject)#1 (1) { 
    ["storage":"ArrayObject":private]=> 
    array(4) { 
    [0]=> 
    string(9) "element 1" 
    [1]=> 
    string(9) "element 2" 
    [2]=> 
    string(9) "element 3" 
    [3]=> 
    string(9) "element 4" 
    } 
} 
object(ArrayObject)#2 (1) { 
    ["storage":"ArrayObject":private]=> 
    array(3) { 
    [0]=> 
    string(9) "element 1" 
    [1]=> 
    string(9) "element 4" 
    [2]=> 
    string(9) "element 5" 
    } 
} 
Questions connexes