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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

8回答

14953閲覧

PHP 配列の中に、指定した文字列が何回登場しているか?

ckaposndbbba

総合スコア210

PHP

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

6クリップ

投稿2015/03/22 11:33

こんにちは。
PHPで、「指定した配列の中で」「何個『PHP』という文字列があるかを知りたい」です。
たとえば、配列は以下のものだったとします。

lang

1$array = array( 2 0 => array( 3 "name" = "PHP", 4 "description" = "PHPは、とっても面白い言語です。" 5 ), 6 1 => array( 7 "name" = "javascript", 8 "description" = "javascriptは、PHPと同じようなことをクライアントサイドで実行することができます。" 9 ), 10 2 => array( 11 "name" = "PHPer", 12 "description" = "PHPを書く人のことです。" 13 ) 14);

それで、この配列の、nameキーの中に、PHPという文字列は何回登場しているか?という。
単に、PHPという文字列が何回...だったら、5回ですが、そうではなくて、
nameの中に入ってる値を対象に探したいんです。
そしたら、2回です。
意味わかりますかね。。

その、◯回という値を知りたいのですが、なにか方法はないでしょうか?
ちなみに、以下のコードとかも書いてみたりしたのですが

lang

1$kai = 0; 2$count = count($array); 3for($i = 0; $i < $count; $i++){ 4 if(stristr($array[$i]['name'],"PHP") !== false){ 5 $kai++; 6 } 7} 8echo $kai . "回";

これだと、値が多いArrayを指定してしまうと、効率が悪くなってしまいます。
関数みたいなものは、あったりしますか?

わかりづらくてすみません。

よろしくお願いします。

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

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

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

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

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

guest

回答8

0

どのくらい大きい配列を想定してるか分かりませんが、
速度的にボトルネックになるくらいのサイズを扱わないといけない場合、
別レイヤーでなんとかするか(DBとか)拡張モジュール作るかで対応しますね。
まぁでも10万件ループするくらいでしたらそれほどかからないと思います。

誤差レベルですがforeach使ったほうが速いです。
キーのことを気にしなくてもいいメリットもあります。

lang

1$kai = 0; 2foreach($array as $val){ 3 if(stristr($val['name'], "PHP") !== false){ 4 $kai++; 5 } 6} 7echo $kai . "回\n";

私でしたら以下のように書きます。

lang

1$kai = count(array_filter($array, function($val){ 2 return stristr($val['name'], "PHP") !== false; 3}));

投稿2015/03/22 13:54

PruneMazui

総合スコア227

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

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

0

>sounisi5011 さんへ

UTF-8はマルチバイト文字を含んでいようとstriposで十分です。
下記のようにマルチバイトの範囲の文字であってもASCIIの範囲に含まれないので、
strposやstr_replace、explodeもそのまま使えます。

ASCII ・・・ [0x00-0x7F] UTF-8 2byte ・・・ [C0-DF][80-BF] UTF-8 3byte ・・・ [E0-EF][80-BF][80-BF] UTF-8 4byte ・・・ [F0-F7][80-BF][80-BF][80-BF] UTF-8 5byte ・・・ [F8-FB][80-BF][80-BF][80-BF][80-BF] UTF-8 6byte ・・・ [FC-FD][80-BF][80-BF][80-BF][80-BF][80-BF]

また、mb_~系の関数はかなり遅いので今回の質問の場合ボトルネックになる可能性もあります。
(対象とする文字列にもよりますが、strstrが1.5倍くらい遅いとすると10倍は遅いです)

投稿2015/03/23 06:03

編集2015/03/23 06:12
PruneMazui

総合スコア227

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

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

PruneMazui

2015/03/23 06:17

ちなみにですがShift-JISやEUC-JPなどのUTF-8以外の文字コードだとマルチバイトの文字コード中にASCIIのコードが現れるためmb_~系を使う必要があります。 (UTF-8以外の文字コードを使うメリットはほとんどないと思っていますが・・・)
sounisi5011

2015/03/24 09:05

ありがとうございます。初めて知りました。
guest

0

これだと、値が多いArrayを指定してしまうと、効率が悪くなってしまいます。

はい。でも、仕方ないかな、と思います。それがArrayの宿命ですから。

投稿2015/03/22 12:12

chokojori

総合スコア971

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

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

chokojori

2015/03/23 07:47

なんかマイナスがついているな。まあ、いいけど。インデックスを使う等の手段があるのは知ったけど、それだと予め決められたキーワードについてしかインデックスできないし、そこまでやるなら全文検索系の機能のあるDBを使うことになりそうな。 書き方を工夫して、コードを多少短くすることはできても、Arrayの要素数に比例して性能劣化するという性質は変わらないですよね。
guest

0

関数の中で関数を呼べばいいかも

xmlを配列にする時参考にしたリンク
http://studio-key.com/157.html

ぶん投げで申し訳ないけど
後はガンバレ

投稿2015/03/24 15:18

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

lang

1print(count(preg_grep('/php/i',array_column($myarr,"name"))));

phpのバージョンが5.5未満であれば、array_columnが使えないので、以下の方法で実装する必要があります。
https://github.com/ramsey/array_column/blob/master/src/array_column.php

また、大文字小文字を区別するのであれば、正規表現を「/PHP/」にしてiオプションを外してください

投稿2015/03/23 07:34

OV222

総合スコア47

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

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

0

そのような標準関数は無いと思います。
もしかしたら、公式ドキュメントの配列関数で探せば見つかるかもしれません。


提示されたコードにはまだ改善の余地があったため、以下に私が改善したコードを記載します。

lang

1$match_keyword='PHP'; 2 3$keyword_count=0; 4foreach($array as $value){ 5 if(stripos($value['name'],$match_keyword) !== false){ 6 $keyword_count++; 7 } 8} 9 10echo $keyword_count.'回';
  • 変数名を変更しました。
  • 検索する文字列を変数に入れ、扱いやすくしてみました。
  • 配列のループ処理はforeachで代用できるため、これに変更しました。
  • stristr()をstripos()に変更しました。

strstr()は、文字列の検出に適していません。
公式ドキュメントにも、以下のようにあります。

もし特定の haystack に needle があるかどうかを調べるだけの場合、 より高速でメモリ消費も少ない strpos() を代わりに使用してください。

公式ドキュメントの記述はこれのみですが、同じ理由でstristr()よりもstripos()が適していると考えました。

投稿2015/03/22 14:33

編集2015/03/24 09:03
sounisi5011

総合スコア697

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

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

0

どのくらい軽減できるかはわかりませんが

lang

1var_dump( count( array_filter( $array, create_function( '$ary', 'return stripos( $ary["name"] ) !== false;' ) ) ) );

データベースとか、インデックスにするならセッターで数えておくとか、いっそインデックス含めたオブジェクトにするとか

投稿2015/03/22 14:16

編集2015/03/22 14:20
miya

総合スコア81

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

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

0

手段の一つとして、事前にインデックスを作って置く方法もあります。

lang

1$idx = array( 2 'PHP' => array(0,2) //"PHP"に該当するのは$array[0]と$array[2] 3 , 'PHPer' => array(2) //"PHPer"に該当するのは$array[2] 4);

これであれば検索部分は以下のように最小限のループ回数ですみます。

lang

1if( array_key_exists('PHP', $idx) ){ 2 $key = $idx['PHP']; 3 4 $len = count($key); 5 for($i=0; $i<$len; $i++){ 6 // $array[ $key[$i] ] に対して処理 7 } 8}

最初にインデックスを作成するコストと、毎回検索するコストを比較して、適した方法を取捨選択されると良いかと思います。

ご参考まで。

投稿2015/03/22 14:05

編集2015/03/22 17:33
munyaX

総合スコア783

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問