質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

733閲覧

unsetを用いた配列の削除について

aae_11

総合スコア178

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/07/29 03:04

以下のコードなのですが、$item_info_listのキーstatusが「0」だった場合、配列を削除することを想定し、書いたコードなのですが、実行しますと

array(1) { [0]=> array(5) { ["id"]=> int(24) ["name"]=> string(10) "テスト2" ["price"]=> int(200) ["img"]=> string(8) "img/test" ["status"]=> string(1) "0" } }

このようになってしまいます。$item_info_listに含まれている2つの配列のキーstatusはどちらも「0」にも関わらず、何故、一つしか配列が削除できないのでしょうか?

$item_info_list = array( 0 => array('id' => 33, 'name' => 'テスト', 'price' => 100, 'img' => 'img/test', 'status' => '0'), 1 => array('id' => 24, 'name' => 'テスト2', 'price' => 200, 'img' => 'img/test', 'status' => '0') ); foreach($item_info_list as $key=> $value){ if($value['status'] == 0){ // var_dump($key); // exit(); unset($item_info_list[$key]); } // var_dump($item_info_list); $item_info_list = array_values($item_info_list); } var_dump($item_info_list); exit();

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

用途が分からないので何とも言えませんけど、これくらいの内容だったら新しく配列作ったほうが分かりやすいコードになると思います。

php

1$new_list = []; 2foreach($item_info_list as $key=> $value){ 3 if($value['status'] === '0') continue; 4 $new_list[$key] = $value; 5} 6var_dump($new_list);

投稿2019/07/29 03:28

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aae_11

2019/07/29 06:43

そういった方法もあるのですね。用途によって使い分けていこうかと思います。
m.ts10806

2019/07/29 06:45

ですので、用途を追記してください。 というか、unset()は今回のような用途で使うことはほとんどないと思います。
aae_11

2019/07/29 06:48

実は、$item_info_listには、固定ではない複数のデータが入るといった感じで、考えていたんですよね。 unset()は通常どのような場合に使われたりするのでしょうか?
m.ts10806

2019/07/29 06:57

よく使うのはメモリの解放。 大きなデータを変数に持たせるとメモリを沢山使うので、 適宜解放することで使っていない変数が保持する領域を解除します。
aae_11

2019/07/29 07:01

そうなんですね。となりますと、配列に格納される小さな値を削除したといった場合には、あまり使わない方が良いのでしょうか?
m.ts10806

2019/07/29 07:06

それももとの配列をどう使いたいかによります。 基本的にですが、PHPはプログラムが最後まで読まれると自動的にメモリを解放するものなので、総データ量が小さいようであれば「削除するのではなく使わないだけにする」という選択肢もあります。 余程パフォーマンスを求めるのであれば使う場面がないとは言えませんが、そういう細かいところよりロジックの見直しの方が何倍も有用です。
guest

0

foreachで配列を回しながら中身を削除したり、($item_info_list = array_values($item_info_list);のように)途中で配列を入れ替えたりと言った操作は、予期しない動作を招きますので、どのように動くのか熟知しているのでなければやってはいけません

条件で配列を振り分けるarray_filter関数を使うのがいいでしょう。

php

1$item_info_list = array( 2 0 => array('id' => 33, 'name' => 'テスト', 'price' => 100, 'img' => 'img/test', 'status' => '0'), 3 1 => array('id' => 24, 'name' => 'テスト2', 'price' => 200, 'img' => 'img/test', 'status' => '0') 4 5); 6 7$filtered = array_filter($item_info_list, function($item) { 8 return $item['status'] !== '0'; 9});

投稿2019/07/29 03:19

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aae_11

2019/07/29 04:02 編集

ご回答ありがとうございます。 少し、疑問に思ったのですが、「return $item['status'] !== '0';」こちらの部分で$item_info_listは多次元配列にもかかわらず、$item[0]['status']のように指定しなくても良いのは何故なのでしょうか...?
maisumakun

2019/07/29 04:08

> $item_info_listは多次元配列なのに、$item[0]['status']のように指定しなくても良いのは何故なのでしょうか...? array_filterのコールバックには、要素が1つずつ送られています。
aae_11

2019/07/29 04:18

ご返信ありがとうございます。 array_filterの仕様のようなものとの解釈で合っていますでしょうか?
guest

0

ベストアンサー

配列を削除することを想定し、書いたコード

コードが提示されていません。
普通にfilter処理すればよいと思います

PHP

1$item_info_list = array( 2 0 => array('id' => 33, 'name' => 'テスト', 'price' => 100, 'img' => 'img/test', 'status' => '0'), 3 1 => array('id' => 24, 'name' => 'テスト2', 'price' => 200, 'img' => 'img/test', 'status' => '0'), 4); 5 6$item_info_list = array_filter($item_info_list,function($x){ 7 return $x["status"]!=="0"; 8}); 9print_r($item_info_list);

参考

削除するときは配列のケツから処理するとよいです

PHP

1$a=["a","b","c","d","e"]; 2for($i=0;$i<count($a);$i++){ 3 if(in_array($a[$i],["b","c","d"])) unset($a[$i]); 4 $a = array_values($a); 5} 6print_r($a);

これをすると"b"を削除したとき後ろのデータがつまってきて、連続データの"c"が
削除されないのでNG

PHP

1$a=["a","b","c","d","e"]; 2for($i=count($a)-1;$i>=0;$i--){ 3 if(in_array($a[$i],["b","c","d"])) unset($a[$i]); 4 $a = array_values($a); 5} 6print_r($a);

後ろから回せばつまっても問題ない

投稿2019/07/29 03:13

編集2019/07/29 05:31
yambejp

総合スコア114837

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/07/29 03:19

配列の下にコードが隠れています。
yambejp

2019/07/29 03:21

失礼しました。見落としていました
yambejp

2019/07/29 05:30

参考処理を追記しておきました
aae_11

2019/07/29 06:41

ご回答ありがとうございます。 for文で回した場合、何故、連続した要素が削除できなかったのかが分かりました。 foreachにしても、 array_values()でキーが振りなおされている為、つまってしまったといった感じだったのですね...
guest

0

$item_info_list = array_values($item_info_list);

これを消してしまえば動きます。

投稿2019/07/29 05:20

takepan1973

総合スコア821

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aae_11

2019/07/29 06:44

他の方のご回答から、理解することができたのですが、$array_valuesが原因でキーが振りなおされてしまっていたことが原因のようでした...
takepan1973

2019/07/29 07:55

それを言うなら array_values() でしょう。 ちなみに削除じゃなくて、 foreach() ループの外に出しても正常に動きます。(というか、それが当初の希望の処理なのでしょうが) foreach() や array_filter() が反復処理を行うということが理解できていれば良いのですが。
aae_11

2019/07/29 08:24

>array_filter() が反復処理 この点につきましては、maisumakunさんにご解説頂き、理解することができました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問