foreach 루프에서 현재 개체 수정


111

foreach루프 내에서 처리되는 현재 개체를 편집 할 수 있는지 궁금합니다.

나는 객체 배열로 작업하고 있으며 $questions내 db에서 해당 질문 객체와 관련된 답변을 살펴보고 싶습니다. 그래서 각 질문에 대답 객체를 가져오고 현재 업데이트 가서 위해 $question 내부foreach내가 다른 곳에서 출력 / 처리를 할 수 있도록 루프를.

foreach($questions as $question){
    $question['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}

ArtjomKurapov와 @topener가 모두 & 기호를 사용하여 '참조로 통과'를 찾고 있다고 제안했듯이. 감사합니다 chaps :) 좋은 하루
되세요

답변:


207

두 가지 방법이 있습니다.

foreach($questions as $key => $question){
    $questions[$key]['answers'] = $answers_model->get_answers_by_question_id($question['question_id']);
}

이렇게하면 키를 저장하여 기본 $questions변수 에서 다시 업데이트 할 수 있습니다.

또는

foreach($questions as &$question){

를 추가 &하면 계속 $questions업데이트됩니다. 그러나 이것이 더 짧더라도 첫 번째 것이 권장된다고 말할 것입니다 (Paystey의 의견 참조)

은 PHP foreach문서 :

루프 내에서 배열 요소를 직접 수정할 수 있으려면 $ value 앞에 &. 이 경우 값은 참조로 할당됩니다.


32
의 참조 foreach는 실제로 권장되지 않습니다 foreach. 루프의 값 부분 주변을 통과하면 예상치 못한 동작이 발생합니다. 더 길 수 있지만 여기서 방법 1을 사용하면 훨씬 안전합니다.
Paystey

1
foreach에서 참조를 사용하여 발생한 문제를 디버깅하는 데 난처한 시간을 보냈습니다. 두 번째 foreach 호출에 동일한 변수 이름을 다시 사용했습니다. 첫 번째를 참조로 전달 했으므로 배열의 마지막 항목을 계속 수정했습니다! 명시 적 인덱스를 사용하면이 문제가 없었을 것입니다.
Hippyjim 2014 년

7
@Paystey 당신은 당신의 출처를 인용하거나 자세한 설명을 줄 수 있습니까?
니코

2
참조를 조작하는 것이 안전하지 않은 이유는 무엇입니까? 어디에서나 참조를 조작해야하는 C / C ++가 안전하지 않습니까? 언어가 아니라 그것을 안전하게 만드는 것은 당신에게 달려 있습니다.
Kalzem

2
@BabyAzerty : Paystey는 "일반적으로"언급하지 않았지만 foreach에서는 다음과 같은 공포에 대해 언급했습니다. stackoverflow.com/questions/3307409/… (@Nico, FYI도 마찬가지입니다.)
Sz.

6

분명히 사용하여 array_map구현하는 컨테이너 사용하는 경우와 ArrayAccess단지 스마트, 의미 론적 방법은 이것에 대해 이동하는 것입니다 파생 개체를?

배열 맵 시맨틱은 내가 본 대부분의 언어와 구현에서 유사합니다. 입력 배열 요소를 기반으로 수정 된 배열을 반환하도록 설계되었습니다 (고수준 무시 언어 컴파일 / 런타임 유형 기본 설정). 루프는 더 많은 논리를 수행하기위한 것입니다.

ID / PK로 개체를 검색하려면 SQL을 사용하는지 여부에 따라 (제안 된 것처럼 보임) 필터를 사용하여 유효한 PK 배열을 얻은 다음 쉼표로 내파하고 SQL IN()절에 배치 하여 결과 집합을 반환합니다. SQL을 통해 여러 번 호출하는 대신 하나의 호출을 수행하여 약간의 call->wait주기를 최적화합니다 . 가장 중요한 것은 내 코드가 어느 정도의 능력을 가진 모든 언어의 누군가에게 잘 읽을 수 있고 우리는 가변성 문제에 부딪히지 않는다는 것입니다.

<?php

$arr = [0,1,2,3,4];
$arr2 = array_map(function($value) { return is_int($value) ? $value*2 : $value; }, $arr);
var_dump($arr);
var_dump($arr2);

vs

<?php

$arr = [0,1,2,3,4];
foreach($arr as $i => $item) {
    $arr[$i] = is_int($item) ? $item * 2 : $item;
}
var_dump($arr);

당신이하고있는 일을 안다면 결코 변경 성 문제가 없을 것입니다 (덮어 쓰기 $arr를 의도한다면 당신은 항상 $arr = array_map명시적일 수 있음 을 염두에 두십시오 .


2
foreach를 수행하는 것보다 훨씬 더 직관적입니다. 이것이 바로이 함수의 목적입니다.
benjaminhull
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.