PHP - Foreach döngüsündeki mevcut nesneyi değiştir


111

Bir foreachdöngü içinde işlenen mevcut nesneyi düzenlemenin mümkün olup olmadığını merak ediyordum.

Bir dizi nesneyle çalışıyorum $questionsve veritabanımda bu soru nesnesiyle ilişkili yanıtları incelemek ve aramak istiyorum. Yani her soru cevap nesneleri getirmek ve akımını güncellemek gitmek için $question içeride benim foreachbaşka bir yere çıkış / işlemini yapabilirsiniz böylece döngü.

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

Hem ArtjomKurapov hem de @topener'in önerdiği gibi, & işaretini kullanarak 'referansla geçiş' arıyordum. Teşekkürler arkadaşlar :) iyi günler
Garbit

Yanıtlar:


207

Bunu yapmanın 2 yolu var

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

Bu şekilde anahtarı kaydedersiniz, böylece ana $questionsdeğişkende tekrar güncelleyebilirsiniz.

veya

foreach($questions as &$question){

Eklemek, güncel &kalacaktır $questions. Ancak daha kısa olmasına rağmen ilkinin tavsiye edildiğini söyleyebilirim (Paystey'in yorumuna bakın)

Başına PHP foreachbelgelerine :

Döngü içindeki dizi elemanlarını doğrudan değiştirebilmek için $ değerin önüne & ile gelin. Bu durumda değer referans olarak atanacaktır.


32
Döngünün değer kısmının etrafındaki geçişlerin öngörülemez davranışlara foreachyol açması nedeniyle , içindeki referanslar gerçekten tavsiye edilmez foreach. Daha uzun olabilir, ancak burada 1. yöntemi kullanarak çok daha güvendesiniz.
Paystey

1
Bir foreach'ta referans kullanmanın neden olduğu bir sorunu ayıklamak için şaşkın bir saat harcadım. İkinci bir foreach çağrısı için aynı değişken adını yeniden kullandım - ilkini referans olarak geçtiğim için dizideki son öğeyi değiştirmeye devam etti! Açık bir dizin kullanmak bu sorunu yaratmazdı.
Hippyjim

7
@Paystey kaynaklarınızdan alıntı yapabilir veya ayrıntılı bir açıklama yapabilir misiniz?
Nico

2
Referansları değiştirmek neden güvensiz olsun? C / C ++, her yerde güvenli olmayan başvuruları işlemeniz gereken yer mi? Güvenli olup olmaması size kalmış, dili değil.
Kalzem

2
@BabyAzerty: Paystey, "genel olarak" referanslar söylemedi, ancak foreachbunun gibi korku ile ilgili olarak: stackoverflow.com/questions/3307409/… (@Nico, FYI da.)
Sz.

6

Kuşkusuz kullanmak array_mapve ArrayAccessnesneleri türetmek için bir konteyner uygulamak , bunun için sadece daha akıllı ve anlamsal bir yol ise?

Dizi haritası anlambilim, gördüğüm çoğu dilde ve uygulamada benzerdir. Giriş dizisi öğesine (yüksek düzeyde dil derleme / çalıştırma türü tercihini göz ardı ederek) dayalı olarak değiştirilmiş bir dizi döndürmek için tasarlanmıştır; bir döngü daha fazla mantık gerçekleştirmek içindir.

Nesneleri ID / PK'ye göre almak için, SQL kullanıp kullanmadığınıza bağlı olarak (önerilmiş görünüyor), bir dizi geçerli PK'ler aldığımdan emin olmak için bir filtre kullanırım, ardından virgülle patlatırım ve bir SQL IN()cümlesine yerleştiririm. sonuç kümesini döndür. call->waitDöngünün bir kısmını optimize ederek SQL aracılığıyla birkaç yerine tek bir çağrı yapar . En önemlisi benim kodum, herhangi bir dilden belli bir derecede yetkinliğe sahip birine iyi okunur ve değişkenlik problemleriyle karşılaşmayız.

<?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);

Eğer ne yaptığınızı biliyorsanız asla değişkenlik problemleri yaşamayacaksınız (üzerine yazmayı düşünüyorsanız $arrher zaman $arr = array_mapaçık ve net olabilirsiniz.


2
Bir foreach yapmaktan çok daha sezgisel - bu tam olarak bu işlev için tasarlandı.
benjaminhull
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.