изменить значение массива объекта с помощью foreach

#php #arrays #object

#php #массивы #объект

Вопрос:

я хочу создать массив объектов, подобных этому:

 [

    'A' => { 'name':'name1', 'family':'family1'},

    'B' => { 'name':'name2', 'family':'family2'},

    'C' => { 'name':'name3', 'family':'family3'},

    'D' => { 'name':'name4', 'family':'family4'},

    'E' => { 'name':'name5', 'family':'family5'},

    'F' => { 'name':'name6', 'family':'family6'},

];
  

у меня есть имя содержимого массива и другое семейство содержимого массива, поэтому я использую цикл foreach. но результат потрясающий. зачем выполнять цикл в каждом, менять все имена и все семейство?

 $name    = [
    'A'=>'name1',
    'B'=>'name2',
    'C'=>'name3',
    'D'=>'name4',
    'E'=>'name5',
    'F'=>'name6'
];
$family  = [
    'A'=>'family1',
    'B'=>'family2',
    'C'=>'family3',
    'D'=>'family4',
    'E'=>'family5',
    'F'=>'family6'
];
$key     = array_keys( $name );
$myArray = array_fill_keys( $key, new stdClass() );

foreach( $myArray as $k => $info ){
    $myArray[$k]->name = $name[$k];
    $myArray[$k]->family = $family[$k];
}
  

и это результат

 [

    'A' => { 'name':'name6', 'family':'family6'},

    'B' => { 'name':'name6', 'family':'family6'},

    'C' => { 'name':'name6', 'family':'family6'},

    'D' => { 'name':'name6', 'family':'family6'},

    'E' => { 'name':'name6', 'family':'family6'},

    'F' => { 'name':'name6', 'family':'family6'},

];
  

Комментарии:

1. Никто не знает причину проблемы?

2. Интересно, вы заполняете свой массив $myArray с помощью $key и ОДНОГО stdObject, все значения указывают на один объект, поэтому, когда вы меняете 1, меняется все $myArray .

Ответ №1:

Обновите свой foreach цикл, чтобы он выглядел примерно так, как показано ниже:

 foreach( $myArray as $k => $info ){
    $myArray[$k] = ['name' => $name[$k] , 'family' => $family[$k]];
}
  

Ответ №2:

Это было бы проще

 $name    = [
    'A'=>'name1',
    'B'=>'name2',
    'C'=>'name3',
    'D'=>'name4',
    'E'=>'name5',
    'F'=>'name6'
];
$family  = [
    'A'=>'family1',
    'B'=>'family2',
    'C'=>'family3',
    'D'=>'family4',
    'E'=>'family5',
    'F'=>'family6'
];

foreach( $name as $k => $info ){
    $t = new stdClass();
    $t->name = $info;
    $t->family = $family[$k];
    $myArray[$k] = $t;
}
  

Результат

 Array
(
    [A] => stdClass Object
        (
            [name] => name1
            [family] => family1
        )
    [B] => stdClass Object
        (
            [name] => name2
            [family] => family2
        )
    [C] => stdClass Object
        (
            [name] => name3
            [family] => family3
        )
    [D] => stdClass Object
        (
            [name] => name4
            [family] => family4
        )
    [E] => stdClass Object
        (
            [name] => name5
            [family] => family5
        )
    [F] => stdClass Object
        (
            [name] => name6
            [family] => family6
        )
)
  

Затем, если вы выполните json_encode() для этого, вы получите то, что хотите

 echo json_encode($myArray);

{
    "A": {
        "name": "name1",
        "family": "family1"
    },
    "B": {
        "name": "name2",
        "family": "family2"
    },
    "C": {
        "name": "name3",
        "family": "family3"
    },
    "D": {
        "name": "name4",
        "family": "family4"
    },
    "E": {
        "name": "name5",
        "family": "family5"
    },
    "F": {
        "name": "name6",
        "family": "family6"
    }
}
  

ОБНОВЛЕНИЕ: Почему у вас возникла проблема с вашим кодом

Эта строка

 $myArray = array_fill_keys( $key, new stdClass() );
  

заполняет массив ссылкой на один объект.

Поэтому, когда вы загружаете данные в объект в массиве, вы заполняете один объект некоторыми данными. На этот объект ссылаются (указывают на него) во всех ваших появлениях массива. Таким образом, вы видите только данные, загруженные на последней итерации цикла, во всех случаях появления массива.

Простой тест, например

 $name    = [
'A'=>'name1',
'B'=>'name2',
'C'=>'name3',
'D'=>'name4',
'E'=>'name5',
'F'=>'name6'
];
$family  = [
    'A'=>'family1',
    'B'=>'family2',
    'C'=>'family3',
    'D'=>'family4',
    'E'=>'family5',
    'F'=>'family6'
];

$key     = array_keys( $name );
$myArray = array_fill_keys( $key, new stdClass() );

// looks like it should fill only the object in the first 'A' occurance
$myArray['A']->one = 1;
print_r($myArray);
  

Результат

 Array
(
    [A] => stdClass Object ( [one] => 1 )
    [B] => stdClass Object ( [one] => 1 )
    [C] => stdClass Object ( [one] => 1 )
    [D] => stdClass Object ( [one] => 1 )
    [E] => stdClass Object ( [one] => 1 )
    [F] => stdClass Object ( [one] => 1 )
)
  

Комментарии:

1. Вопрос, который я задал, является примером. Мне нужно создать стандартный класс со специальной сортировкой в свойстве в моем исходном коде. Итак, я действовал следующим образом. $x = { prop1:null, prop2:null, … , propN:null} $myArray = array_fill_keys($key, $ x ); и в цикле foreach задайте значение для каждого свойства. вы знаете, почему цикл при каждом запуске сохраняет все значения?

Ответ №3:

 $myArray = [];
foreach($name as $k => $v){
    $myArray[$k] = (object)['name'=>$v, 'famili'=>$family[$k]];
}
  

Комментарии:

1. Хотя этот код может отвечать на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, улучшает его долгосрочную ценность.

2. Хотя то, что вы написали, может дать ответ на вопрос, однако, кажется, что в нем немного не хватает объяснения и может вызвать недоумение у других пользователей. Не могли бы вы, пожалуйста, расширить свой ответ, чтобы он был понятнее и доступнее? Это позволит получить более точные ответы и поможет будущим пользователям понять, как была решена проблема.