germn
@germn

Как уникализировать массив ссылок на объекты по самим ссылкам, а не по значению объектов?

$a = 1;
        $b = 2;

        $array[] = &$a; // Два элемента - ссылка на $a
        $array[] = &$a;

        $array[] = &$b; // Один элемент - ссылка на $b
        
        $array[0]++;
        // Естественно изменилось и значение $array[1]:
        print_r($array);
        // Array ( [0] => 2 [1] => 2 [2] => 2 )
        
        print_r(array_unique($array));
        // Array ( [0] => 2 ) 
        // Из трех ссылок, две из которых уникальны, осталась только одна



Мне требуется, чтобы после операции уникализации на выходе был массив, содержащий одну ссылку на $a и одну на $b.


Как реализовать?

Спасибо!

Upd:

Как вообще сравнить две ссылки на эквивалентность?

Для кода выше:
$array[0] === $array[1] // true
$array[0] === $array[2] // true :(

Ответ на этот вопрос подсказали в комментариях:
function is_ref_to(&$a, &$b)
{
    $t = $a;
    if($r=($b===($a=1))){ $r = ($b===($a=0)); }
    $a = $t;
    return $r;
}
  • Вопрос задан
  • 3325 просмотров
Решения вопроса 1
mark_ablov
@mark_ablov
Писать свою версию array_unique, ибо сравнение внутри библиотечной идёт по строковым значениям — (string)s1 == (string)s2.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
BoShurik
@BoShurik
Symfony developer
spl_object_hash не подойдет?

Будет что-то вроде:
$id = spl_object_hash($a);
$array[$id] = $a;
Ответ написан
Stdit
@Stdit
$s = new SplObjectStorage();
$o1 = new StdClass;
$o1->a = 1;
$o2 = new StdClass;
$o2->a = 1;
$o3 = new StdClass;
$o3->b = 3;
$s->attach($o1);
$s->attach($o2);
$s->attach($o1);
$s->attach($o3);
var_dump(iterator_to_array($s));
array(3) {
  [0]=>
  object(stdClass)#2 (1) {
    ["a"]=>
    int(1)
  }
  [1]=>
  object(stdClass)#3 (1) {
    ["a"]=>
    int(1)
  }
  [2]=>
  object(stdClass)#4 (1) {
    ["b"]=>
    int(3)
  }

Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы