PHP - найти объект по ключу в массиве объектов, обновить его значение - PullRequest
0 голосов
/ 27 октября 2018

У меня есть массив объектов, и я хочу обновить атрибут одного из объектов.

$objs = [ ['value'=>2, 'key'=>'a'], ['value'=>3, 'key'=>'b'] ];

Допустим, я хочу установить 'значение' объекта с помощью 'key' => 'a' равным 5.

Помимо итерации по массиву в поисках ключа, есть ли более быстрый / эффективный способ сделать это?

Спасибо.

РЕДАКТИРОВАТЬ : Существует спор о том, почему я не могу использовать ассоциативный массив. Это потому, что этот массив получен из значения JSON.

Если мой объект JSON такой:

"obj":{"a":{"key":"a", "value":2}, "b":{"key":"b", "value":3}}

Нет гарантии, что порядок объектов будет сохранен, что требуется.

Следовательно, мне нужен индекс в каждом объекте, чтобы иметь возможность сортировать его с помощью usort (). Так что мой JSON должен быть:

"obj":{"a":{"key":"a", "value":2, "index":1}, "b":{"key":"b", "value":3, "index":2}}

Но я не могу использовать usort () для объекта, только для массивов. Так что мой JSON должен быть

"obj":[{"key":"a", "value":2, "index":1}, {"key":"b", "value":3, "index":2}]

Что подводит нас к первоначальному вопросу.

Ответы [ 4 ]

0 голосов
/ 27 октября 2018

Я хочу порекомендовать вам изменить структуру вашего массива озера так:

$objs = [ 
'a' => ['value'=>2, 'key'=>'a'], 
'b' => ['value'=>3, 'key'=>'b'] 
];

А теперь

if( array_key_exists( 'a', $objs )) {
  $objs ['a'] ['value'] = 5;
}

У меня было так изначально.Но мне нужно, чтобы объекты имели индексное значение, чтобы я мог запустить usort () в основном массиве.Это потому, что массив исходит из JSON, где первоначальный порядок не соблюдается

Затем создайте массив index:

// When fill `$objs` array
$objs = [];
$arrIndex = [];
$idx = 0;
foreach( $json as $item ) {
  $arrIndex [ $item ['key']] = $idx;
  $objs [$idx ++] = $item;
}

// And your task:

if( array_key_exists( 'a', $arrIndex )) {
  $objs [ $arrIndex ['a']] ['value'] = 5;
}
0 голосов
/ 27 октября 2018

Используя array_column(), вы можете получить все значения с индексом key в массивах. Затем вы можете найти первое вхождение значения a, используя array_search(). Это вернет только первый индекс, где он найдет значение. Затем вы можете просто заменить это значение, так как теперь у вас есть индекс этого значения.

$keys = array_column($objs, 'key');
$index = array_search('a', $keys);

if ($index !== false) {
    $objs[$index]['value'] = 5;
}

См. живое демо .

0 голосов
/ 27 октября 2018

Помимо перебора массива в поисках ключа, есть ли более быстрый / эффективный способ сделать это?

Вы должны заплатить цену итерации в любом случае.

Вы можете найти интересующий объект в вашей коллекции (занимает линейное время) или сформировать некую структуру словарных данных, например, хеш-таблицу (занимает линейное время), а затем найти интересующий объект в постоянное время.

Здесь нет бесплатных обедов.

0 голосов
/ 27 октября 2018

Вы можете сделать массив ассоциативно связанным со столбцом массива. Таким образом, вы можете напрямую присвоить значение.

$objs = [ ['value'=>2, 'key'=>'a'], ['value'=>3, 'key'=>'b'] ];
$objs = array_column($objs, null, "key");
$objs['a']['value'] = 5;

https://3v4l.org/7tJl0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...