PHP質問・雑談スレ【初心者お断り(ROM歓迎)】©5ch.net
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん 転載ダメ©2ch.net
2016/04/22(金) 08:58:11.47ID:???初心者お断り(ROM歓迎)と書いてますが、初心者用のスレが用意されているからで、
難しい質問や話題をしなければいけないわけではありません。
PHPマニュアルの読み方を概ね理解していて、関数リファレンスが正しく読める方用のスレです。
PHP未導入の方や、手取り足取りが必要な初心者の方はくだスレへどうぞ。
【PHP】下らねぇ質問はここに書き込みやがれ 4
http://echo.2ch.net/test/read.cgi/tech/1457792733/
その他リンク
・PHPマニュアル
https://secure.php.net/manual/ja/index.php
・コードテスト・貼り付け用
http://ideone.com/
・プログラミングのお題スレ Part8 (求PHPer参戦)
http://echo.2ch.net/test/read.cgi/tech/1444216746/
このスレで扱う話題
・PHPのコード,設定や設定値に関する質問
・常識的範囲内でのコードレビュー依頼・改良相談
・PECL,PEARに関する質問
・PHP新機能やPHP関連トレンドの話題
(FWや非公式ライブラリの話題や特徴比較は良いが使い方から先の話題は専スレへ)
・PHPのバグ発見報告・公式に報告する前の検証依頼
このスレで扱わない話題
・直接関係ない○○特有の質問(専スレへ)
(HH,エディタ,IDE,サーバ,OS,DB,SQL,FW,テンプレート,非公式ライブラリ・アプリケーション等)
・PHPの改造
0002nobodyさん
2016/04/22(金) 16:35:57.63ID:???"C" => 10, "D" => ["E" => ["a" => 1, "b" => 2], "F" => ["a" => 1, "b" => 2]]];
こんな感じのわりと綺麗じゃない多次元連想配列があります。
9個ある値 A>a A>b B>a B>b C D>E>a D>E>b D>F>a D>F>b のうち、
$value % 2 == 0であるものを削除したいです。
上の例だと残るのは A>a B>a D>E>a D>F>a の4つになります。
1次元の配列だとforeachしてunset($a[$key])するだけなので簡単なのですが、
この場合どうしたらいいでしょうか?
array_walk_recursive($a, function(&$item) {
if ($item % 2 == 0) {
unset($this);
}
}
とか出来ればいいのですが出来ないので、今は苦肉の策として、
$item = null;
としています。
0003nobodyさん
2016/04/22(金) 16:58:24.51ID:???それでもこの板に立てたいということワッチョイつければよいかと。
【PHP】下らねぇ質問はここに書き込みやがれ 4 [無断転載禁止]©2ch.net
http://echo.2ch.net/test/read.cgi/tech/1457792733/
0004nobodyさん
2016/04/22(金) 17:31:45.64ID:???こんな感じじゃろか
function array_unset_recursive(&$array) {
foreach ($array as $key => &$value) {
if (is_array($value)) {
array_unset_recursive($value);
} else {
if ($value % 2 == 0) {
unset($array[$key]);
}
}
}
}
array_unset_recursive($a);
>>3
監視乙
0005nobodyさん
2016/04/22(金) 17:49:07.90ID:???0006nobodyさん
2016/04/22(金) 17:56:54.01ID:???なんでこっちにいちいち来て煽るかなぁw
00072
2016/04/22(金) 18:09:14.36ID:???ありがとうございます。
自身を参照出来るよう、objectに変換したりして試してましたがどうもうまくいきませんでした。
そちらの関数でうまくいったので使わせて頂きます。
どうもありがとうございました。
0008nobodyさん
2016/04/22(金) 18:10:00.61ID:???function f1(&$v)
{
if(is_array($v)) {
$v=array_filter($v,'f1');
return !empty($v);
}
return $v%2!=0;
}
$a=array_filter($a,'f1');
まあ再帰呼び出しのために名前付き関数定義は避けられないんじゃないかね。
00092
2016/04/22(金) 18:20:03.65ID:???ありがとうございます。
再帰だとループ文使わないでうまく出来るんですね。
だいぶすっきりしたコードに見えます。
情報処理試験の時にやったきりで、苦手なので避けてましたが、
この機会に勉強しなおしてみます。
お二方どうもありがとうございました。
0010nobodyさん
2016/04/22(金) 18:23:57.51ID:???たとえば例の "C" => 10 が "C" => ["b" => 10] だった場合、
結果は "C" => [] となるべきか、"C"ごと消えるべきかが不明確なままだと思うけどいいのかな。
00112
2016/04/22(金) 18:32:43.50ID:???なるほど、同じ結果に見えた>>4さんと>>8さんのコードにそんなところで差があるとは思いもしませんでした。
不必要な情報は出来るだけ消したい感じなので、>>8さんのコードのほうがベターな感じですね。
コードをじっくり見比べてみて、両者の結果の違いをどうしてそうなるのか考えてみたいと思います。
的確なツッコミありがとうございました。
0012nobodyさん
2016/04/22(金) 18:37:20.06ID:???その点での違いは empty判定だから、>>4 だって同等のことをして同じ結果を得られるようにできるよ。
0013nobodyさん
2016/04/22(金) 18:40:47.13ID:???http://melpon.org/wandbox/permlink/iNRlUflNSv8UudAP
0014nobodyさん
2016/04/22(金) 18:46:44.41ID:???警告
配列の内容がコールバック関数内で変更された場合 (たとえば要素が追加されたり削除されたりなど) のこの関数の挙動は未定義です。
0015nobodyさん
2016/04/22(金) 18:46:46.81ID:???こりゃひでえw
00168
2016/04/22(金) 18:47:54.16ID:???やっぱトリッキーなことはやるもんじゃないね。
すまん
0017nobodyさん
2016/04/22(金) 18:48:35.81ID:???00188
2016/04/22(金) 18:56:24.83ID:???新しいリファレンスだと
> 配列の内容がコールバック関数内で変更された場合
だけど、おれの手元の古いリファレンスだと
> コールバック関数によって配列自身を変更することはできません
になってて、ちょっとニュアンスが違うようにも思えるが、実装が変わったということなのか、最初から読み誤りだったのか、さて。
0019nobodyさん
2016/04/22(金) 18:56:40.17ID:???> 再帰呼び出しのために名前付き関数定義は避けられないんじゃないかね。
についてだけでいえばこう書ける。
<?php
$f = function (&$v) use (&$f) {
if(is_array($v)) {
$v=array_filter($v,$f);
return !empty($v);
}
return $v%2!=0;
};
$a = ["A" => ["a" => 1, "b" => 2], "B" => ["a" => 1, "b" => 2],
"C" => 10, "D" => ["E" => ["a" => 1, "b" => 2], "F" => ["a" => 1, "b" => 2]]];
print_r($a);
$a=array_filter($a,$f);
print_r($a);
くだ質で十分な内容のように思うけどな。
00208
2016/04/22(金) 18:59:17.03ID:???この辺の挙動についてどっかに明記されてる?
つか ID 出ないの面倒くさいね。
0021nobodyさん
2016/04/22(金) 20:03:53.34ID:???ハッシュテーブルなら問題ないんでないー。
0022nobodyさん
2016/04/22(金) 21:14:02.83ID:???配列に対する操作を行ってる最中に配列を変更するという点で >>14 の状況と似てると思うんだけど、やっていいとか悪いとかの明確な記述って見たことある?
例えば次以降で回ってくるはずだった要素を unset したらどうなるかとか、要素を追加したらどうなるかとか、実験的に確認はしてるけど仕様の裏付けが無ければ >>13 の二の舞になる。
そこら辺怖いから、どうしてもループ中で配列の変更を行いたい場合はその配列そのものを foreach するんじゃなく、配列の array_keys を foreach してお目当ての配列を添え字アクセスするようにしたりしてるけど。
0023nobodyさん
2016/04/23(土) 00:27:00.66ID:???5.x系までのお話
0025nobodyさん
2016/04/23(土) 09:09:36.34ID:???うは、大分分かりづらいなw
でもわざわざそういう実装にしてるということは、foteach内でのよくある要素の追加削除には対応するという意思があるんだろうから、バージョンアップしてもその動作は保証されると見ていいのかな。
読み応えあった。ありがとう。
>>24
おれはこのスレの 8 と他いくつかで、あっちのスレでは一番たくさん反対してた者だが、
あの手のやつはスレを立てるだけ立ててロクに書かない書けないやつだと思うよ、どの板にもいるように。
いまこのスレでやってることだって分散させずあっちのスレで充分だし、内容だって webprog ですらないからな。
あっちで httpd の設定が云々言ってる方がよほど webprog の話題だろう。
傾向の違う充分なボリュームが出るなら住み分けには賛成だが、安易に分離して人が多ければ進む議題が放置されるのはかんべん。
0026nobodyさん
2016/04/23(土) 11:14:52.95ID:???嫌う人が出てもしょうがない。
テンプレ削りすぎたせいもあるんだろうが、正直脱線しすぎ。
数人のサポセンになってて今の向こうは読む気すらおきないってのが正直なところ。
このスレがオリジナル踏襲してるかというと全然違うけどね。
もう2chでやること自体だめっぽいな。
0027nobodyさん
2016/04/23(土) 12:26:11.75ID:???0029nobodyさん
2016/04/23(土) 17:57:37.94ID:???0030nobodyさん
2016/04/23(土) 17:59:03.79ID:???手取り足取りスレ化してるし
誘導も出来ない一部荒らし回答者のオナニー
0032nobodyさん
2016/04/24(日) 05:17:57.29ID:???foreachの最中に、コンテナを変更したら、たいていの言語ではバグる。
Ruby, Python も参照(シャローコピー)を持ちまわっているから
Rubyでは、freezeで変更不可にできる。
Pythonでは、タプルが変更不可
0035nobodyさん
2016/04/24(日) 11:25:55.69ID:???じゃあPHP7ではどうなのかというのは元回答が追記されてるのでそっち読むといいよ。
http://stackoverflow.com/questions/10057671/how-does-foreach-actually-work/14854568#14854568
0036nobodyさん
2016/04/24(日) 11:51:50.46ID:???それは仕様じゃなくて実装の話じゃない?
どういう仕様に基づいてそう実装されてるかじゃなく、こう実装されてるからこう動くってことを言ってるように見えるけど。
だから副作用的な挙動で説明してるんじゃないのかな。
仕様ってもっと端的に、foreach内で配列を変更していいor悪いとかいう話で。
英語得意じゃないから、読み取れてないだけというなら指摘してくれ。
0037nobodyさん
2016/04/24(日) 11:54:23.05ID:???>>25の人じゃないってことでいいのかな。
翻訳版にも書かれてるとおり、バージョン依存の挙動調査に過ぎないよ。
0038nobodyさん
2016/04/24(日) 12:01:12.77ID:???バージョン依存の挙動調査ということは、仕様としては未定義だから使うべきではないって判断になる?
おまえならどうする?
0039nobodyさん
2016/04/24(日) 12:05:47.50ID:???なお、PHP 7 以降については、zval の構造などが変わりますので、一部の特殊な挙動は同様に動作しなくなる可能性があります。(実際に「イテレーション中の内部配列ポインタの変更」などでの一部の挙動が変わっているのを確認しています。)
翻訳版にもこう書かれているというのに。
ループ内で要素数の変更を行うコーディングはしないようにしてるよ。
要素の変更は普通に参照なりkey経由で行うけれど。(array_filter内で変更することとこれとは違うからね)
0040nobodyさん
2016/04/24(日) 12:43:43.26ID:???> 翻訳版にもこう書かれているというのに。
いやさ、おれは最初から実装じゃなく仕様を聞いてるんだってばさ。
ようするに仕様としては未定義なんだよな?
もちろん実装から解説したこの記事は大いに参考になったけどさ。
> ループ内で要素数の変更を行うコーディングはしないようにしてるよ。
やっぱそうなるよね。そこはおれも同じだ。
array_filter の事情と違うことも分かってるつもりだよ(仕様としても書かれてたし)。
0042nobodyさん
2016/04/24(日) 12:51:57.25ID:???0043nobodyさん
2016/04/24(日) 13:01:46.90ID:???今のところそういう必要のある流れじゃないでしょ
0044nobodyさん
2016/04/24(日) 13:15:20.86ID:???メジャーバージョンが変われば今までのプログラムは動かないと考えて、
新しい対処をするのがベターだろう。どの言語でお。
0045nobodyさん
2016/04/25(月) 04:08:32.95ID:???ループ中にコンテナをいじるとバグる
そういうプログラミングをしていると、
もし内部的に、Javaのような、parallel for などで並行処理にしようとしても使えない
0046nobodyさん
2016/04/25(月) 06:19:24.84ID:???0047nobodyさん
2016/04/25(月) 07:27:35.20ID:???ソートみたいな並べ替えも含むかな。
php については >>35 の php7 のケースによれば、要素の更新の場合もクセがありそうだけど、これはコンテナをいじるというのとは違うように思う。
0048nobodyさん
2016/04/25(月) 07:51:20.41ID:???0050nobodyさん
2016/04/27(水) 11:16:53.40ID:???0051nobodyさん
2016/04/28(木) 01:54:25.30ID:???0052nobodyさん
2016/04/29(金) 14:00:02.56ID:???ウインドウサイズを認識した分岐ができるようになってほしい。
ソースレベルでも入・出力を振り分けたい。
0054nobodyさん
2016/04/30(土) 10:22:33.78ID:???出来るから。勉強不足すぎるわ。デバイス判定、画面サイズ判定普通に出来るから。
おまえの問題でしかないだろバカ
■ このスレッドは過去ログ倉庫に格納されています