なずブログ

インフラSE、Java開発、リモートワークエンジニアな人のメモ帳

フラット型多次元連想配列のフィルター

f:id:nazuna_0124:20170312082946p:plain

飲み屋でしてはならない話題に政治、宗教、野球というのがあるそうです。

オブジェクト指向の盛り上がり(?)を考えると、プログラミングの設計指向(こういえばいいの?)

も入れてあげてもいいんじゃとか思ってます。


にもかかわらず、オブジェクト指向と民主主義ってなんとなく似てるよね!

と、より危険な方の比喩を使ってみたり。

民主主義の原則

  • 自由
  • 平等
  • 友愛

オブジェクト指向の原則

  • 隠蔽
  • 継承
  • 多相性


ほらほら!


民主主義とは多数決のことである、というのはよくある誤解らしいので、


オブジェクト指向とはクラスを使うことであると誤解して突き進んで見る方向性。


さて、では本日のお題は前記事で定義したフラット型多次元連想配列のフィルタについてです。

組み込み関数は大抵一次元用なので自分でなんとかするしかないのです。


以前に紹介したGinqはこっそり挫折しました……。


テストページはこちら


項目ごとに抽出できるってだけのページです。


趣味の項目だけ、曖昧検索ちっく。といっても1単語だけですけれど。


<?php
   require_once ('common.php');
    $array[] = ['id'=>'0001','name' => 'AAA' ,'age' => '20' ,'hobby'=>'game,soccer','created'=>'2017/01/01'];
    $array[] = ['id'=>'0002','name' => 'BBB' ,'age' => '30' ,'hobby'=>'game','created'=>'2016/01/01'];
    $array[] = ['id'=>'0003','name' => 'CCC' ,'age' => '40' ,'hobby'=>'','created'=>'2016/01/04'];
    $array[] = ['id'=>'0004','name' => 'DDD' ,'age' => '50' ,'hobby'=>'game,soccer,fishing','created'=>'2017/02/01'];
    $array[] = ['id'=>'0005','name' => 'EEE' ,'age' => '60' ,'hobby'=>'baseball,soccer','created'=>'2017/03/01'];
    

   
    $data = new aryFilter();
    $data->setData($array);
//    $data->extMatch('name','BBB'); //一致
//    $data->extMore('age','30'); //以上
//    $data->extLess('age','50'); //以下
//    $data->extStrpos('hobby','game'); //含まれる
//    
//    echo var_dump($data->resFilter())
// 
//    echo var_dump($data->FilterDiff());     
    

    $form = array('id','name','ageMore','ageLess','strpos');
    
    if(!empty($_POST)){
        foreach ($_POST as $key => $val){
            $p[$key] = htmlspecialchars($val,ENT_QUOTES,'UTF-8');
        }
    }else{
        foreach($form as $val)
            $p[$val] = '';          
    }
  
      
    if (!empty($p['id'])){
        $data->extMatch('id',$p['id']);
    }
    
    if (!empty($p['name'])){
        $data->extMatch('name',$p['name']);
    }
    
    if (!empty($p['ageMore'])){
        $data->extMore('age', $p['ageMore']);
    }
    
    if (!empty($p['ageLess'])){
        $data->extLess('age', $p['ageLess']);
    }
    
    if (!empty($p['strpos'])){
        $data->extStrpos('hobby', $p['strpos']);
    }

    $outHtml = $data->resFilter();
    
  
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>filterTest</title>
    </head>
    <body>
        <form method="post" action="">
            <div>ID:<input type="text" name="id" value="<?= $p['id'] ?>"></div>
            <div>名前:<input type="text" name="name" value="<?= $p['name'] ?>"></div>
            <div>年齢:<input type="text" name="ageMore" value="<?= $p['ageMore'] ?>">以上<input type="text" name="ageLess" value="<?= $p['ageLess'] ?>">以下</div>
            <div>趣味:<input type="text" name="strpos" value="<?= $p['strpos'] ?>"></div>
            <div><input type="submit" value="絞込み" ></div>
        </form>
        <table>
           
            <?php if(!empty($outHtml)): ?>
                <tr>
                    <?php foreach($outHtml[0] as $key => $val): ?>
                        <th><?= $key ?></th>
                    <?php endforeach; ?>
                </tr>

                <?php foreach($outHtml as $row => $key): ?>
                    <tr>
                        <td><?= $key['id'] ?></td>   <td><?= $key['name'] ?></td> <td><?= $key['age'] ?></td> <td><?= $key['hobby'] ?></td> <td><?= $key['created'] ?></td>
                    </tr>
                <?php endforeach; ?>
            
                <?php else: ?>
                       検索結果がありません
            <?php endif; ?>
        </table>
    </body>

</html>

クラスのメソッド用にコメアウトをしつつ。


少なくともPHPの部分はわかりやすーい!


さて…肝心のクラス側はこちら

<?php
class aryFilter{
    private $_data;//元データ
    private $_resData;//フィルター結果
    
    function setData($array){
        $this->_data= $array;
        
        $this->_resData = $array; //html表示対策のためセット
    }

    function putAllData(){
        return $this->_data;
    }
    
        
        //フィルタ結果がなければ格納。連続でフィルタを行いたいのでsetDataで使用しない。
        private function exitsResData(){
            
            if(empty($this->_resData)){
                $this->_resData = $this->_data; 
            } 
  
        }
    
    //フィルター後の逆を算出。(含まれないを抽出したいときに)
    function FilterDiff(){
        $this->exitsResData (); //意味ないけど一応、セットしておく。
        $responseArray = $this->_data;
        
  
        foreach ($responseArray as $Row => $resVal){
            
                foreach($this->_resData as $key => $dataVal){
                   
                     if($dataVal['id'] == $resVal['id']){
                         
                         unset($responseArray[$Row]);
                     }
                }
            
        }
        
        return $responseArray;
    }
        
        
    
    //含まれる処理。
    function extStrpos($inkey,$inval){
        $this->exitsResData();
        
        $ary = $this->_resData;
        $putary = [];
   
  
        foreach ($ary as $row){
            foreach ($row as $key => $val){
                if($key == $inkey){  
                    if (strpos($val,$inval)!==False){
                        $putary[] = $row;
                    }
                }
            }  
        }
        
        $this->_resData =$putary;

    }    
        
        
    
    //以上なので注意。演算子を変数にできるんかな。
    function extMore($inkey,$inval){
        $this->exitsResData();
        
        $ary = $this->_resData;
        $putary = [];
   
        
        foreach ($ary as $row){
            foreach ($row as $key => $val){
                if($key == $inkey){
                    if ($val >= $inval){
                        $putary[] = $row;
                    }
                }
            }  
        }
        
        $this->_resData =$putary;
    }
   
    
     function extLess($inkey,$inval){
        $this->exitsResData();
        
        $ary = $this->_resData;
        $putary = [];
   
        
        foreach ($ary as $row){
            foreach ($row as $key => $val){
                if($key == $inkey){
                    if ($val <= $inval){
                        $putary[] = $row;
                    }
                }
            }  
        }
        
        $this->_resData =$putary;
    }
    
    //キーと文字列を指定。一致するものだけを抽出。
    function extMatch($inkey,$inval){
        $this->exitsResData();
        
        $ary = $this->_resData;
        $putary = [];
        
        foreach ($ary as $row){
            foreach ($row as $key => $val){
                if($key == $inkey){
                    if ($val == $inval){
                        $putary[] = $row;
                    }
                }
            }  
        }
        
        $this->_resData =$putary;
        
    }
     
        //フィルター結果を出力。
        function resFilter(){
            return $this->_resData;
        }
    
}
?>


隠蔽とはコードの無様さを隠することである!(断言)


そんなことゆっても、他に思いつかなかったんだもん!!!


使い回し簡単ですし、メソッド足せば機能追加も簡単ですし


クラスって素敵!!


でもVBAのクラスモジュールさん、あなたはだめです。