Cake PHPの覚書

Hash:get() | パスを指定して配列から1つの値を取り出す

元データ配列:$ary
	array (size=4)
	  0 => string 'dummy' (length=5)
	  'yasai' =>
	    array (size=2)
	      0 => string 'nasu' (length=4)
	      'x' => string 'tomato' (length=6)
	  'animal' =>
	    array (size=3)
	      'a1' => string 'neko' (length=4)
	      'a2' => string 'inu' (length=3)
	      'musi' =>
	        array (size=2)
	          0 => string 'kabuto' (length=6)
	          1 => string 'kuwagata' (length=8)
	  1 => string 'dummy2' (length=6)
	

ソースコード
$ary2=Hash::get($ary, 'yasai.0');

抽出後のデータ:$ary2
string 'nasu' (length=4)
	

ドキュメント サンプル

Hash::combine | 多重配列から構造変換した配列を取得

Hash::combineは配列を別の構造に変換するときに使う。
下記の例ではよくあるパターンとして、キーを連番からIDに構造変換をする例を示す。

元データ配列:$ary
	array (size=6)
	  0 =>
	    array (size=2)
	      'id' => int 101
	      'name' => string 'ネコ' (length=6)
	  1 =>
	    array (size=2)
	      'id' => int 102
	      'name' => string 'ネズミ' (length=9)
	  2 =>
	    array (size=2)
	      'id' => int 103
	      'name' => string 'ウシ' (length=6)
	  3 =>
	    array (size=2)
	      'id' => int 104
	      'name' => string 'トラ' (length=6)
	  4 =>
	    array (size=2)
	      'id' => int 105
	      'name' => string '鵜' (length=3)
	  5 =>
	    array (size=2)
	      'id' => int 106
	      'name' => string '猿' (length=3)
	

ソースコード
$ary2=Hash::combine($ary, '{n}.id','{n}');
データのキーがインデックスでなく文字列である場合
$ary2=Hash::combine($ary, '{s}.id','{s}');

抽出後のデータ:$ary2
	array (size=6)
	  101 =>
	    array (size=2)
	      'id' => int 101
	      'name' => string 'ネコ' (length=6)
	  102 =>
	    array (size=2)
	      'id' => int 102
	      'name' => string 'ネズミ' (length=9)
	  103 =>
	    array (size=2)
	      'id' => int 103
	      'name' => string 'ウシ' (length=6)
	  104 =>
	    array (size=2)
	      'id' => int 104
	      'name' => string 'トラ' (length=6)
	  105 =>
	    array (size=2)
	      'id' => int 105
	      'name' => string '鵜' (length=3)
	  106 =>
	    array (size=2)
	      'id' => int 106
	      'name' => string '猿' (length=3)
	





3次元配列から取り出す例
$categoryList=Hash::combine($categoryList, '{n}.{n}.id','{n}.{n}.name');
	array(
		(int) 1 => 'ねずみ',
		(int) 2 => 'うし',
		(int) 3 => 'とら',
		(int) 5 => '鵜',
		(int) 6 => '猿',
		(int) 7 => '鳥',
		(int) 15 => 'かに'
	)
	


ドキュメント サンプル

Hash::exitract | 多重配列から必要な情報だけを抽出

データ(エンティティのリスト)からidリストを抽出する
$list=Hash::extract($data, '{n}.id');

条件で絞り込む
$list=Hash::extract($data, '{n}[id>103]');

複数の条件指定かつ、特定のフィールドをリストとして取得する
$list=Hash::extract($data, '{n}[animal_kind=1][category=1].animal_name');

元データ:$ary
	array (size=6)
	  0 =>
	    array (size=2)
	      'id' => int 101
	      'name' => string 'ネコ' (length=6)
	  1 =>
	    array (size=2)
	      'id' => int 102
	      'name' => string 'ネズミ' (length=9)
	  2 =>
	    array (size=2)
	      'id' => int 103
	      'name' => string 'ウシ' (length=6)
	  3 =>
	    array (size=2)
	      'id' => int 104
	      'name' => string 'トラ' (length=6)
	  4 =>
	    array (size=2)
	      'id' => int 105
	      'name' => string '鵜' (length=3)
	  5 =>
	    array (size=2)
	      'id' => int 106
	      'name' => string '猿' (length=3)
	

ソースコード id>103の式で絞り込む。
$ary2=Hash::extract($ary, '{n}[id>103]');
抽出後のデータ:$ary2
	array (size=3)
	  0 =>
	    array (size=2)
	      'id' => int 104
	      'name' => string 'トラ' (length=6)
	  1 =>
	    array (size=2)
	      'id' => int 105
	      'name' => string '鵜' (length=3)
	  2 =>
	    array (size=2)
	      'id' => int 106
	      'name' => string '猿' (length=3)
	





ソースコードその2
idのみ配列として抜き出す。
$ary3=Hash::extract($ary, '{n}.id');
抽出後のデータ:$ary3
	array (size=6)
	  0 => int 101
	  1 => int 102
	  2 => int 103
	  3 => int 104
	  4 => int 105
	  5 => int 106
	

delete_flg=0且つfile_nameプロパティのみ抽出する例。
$delFns=Hash::extract($faData, '{n}[delete_flg=0].file_name');
ドキュメント サンプル

Hash::insert | 配列にキーやパスを指定して値を挿入する

Hash::insert(配列, キーまたはパス, 追加する値)
パスを指定すると、複数に値を挿入できる。

基本 ソースコード
	$data=array(
			'neko'=>'ネコ',
			'yagi'=>'山羊',
	);
	$data2=Hash::insert($data, 'kani', 'カニ');
	

出力
	array(
		'neko' => 'ネコ',
		'yagi' => '山羊'
	)
	
	array(
		'neko' => 'ネコ',
		'yagi' => '山羊',
		'kani' => 'kani'
	)
	
※配列も値として挿入可能
{n}を使って複数のポイントに挿入する
データのすべてのエンティティにプロパティを追加することができる。

ソースコード
	$data=array(
			array(
				'name'=>'虎次郎',
				'kind'=>'ネコ',
			),
			array(
				'name'=>'王大人',
				'kind'=>'犬',
			),
	);
	$data2=Hash::insert($data, '{n}.flg', 4);
	

出力
	array(
		(int) 0 => array(
			'name' => '虎次郎',
			'kind' => 'ネコ'
		),
		(int) 1 => array(
			'name' => '王大人',
			'kind' => '犬'
		)
	)
	
	array(
		(int) 0 => array(
			'name' => '虎次郎',
			'kind' => 'ネコ',
			'flg' => (int) 4
		),
		(int) 1 => array(
			'name' => '王大人',
			'kind' => '犬',
			'flg' => (int) 4
		)
	)
	
※パスは{n}だけでなく{s}も使える。

ドキュメント サンプル

Hash::remove | パスに該当する値を削除する

検証1

	$data=array(
			'neko'=>'ネコ',
			'yagi'=>'ヤギ',
			'sakana'=>array('same'=>'サメ','medaka'=>'メダカ',),
	);
	
	$data2=Hash::remove($data, 'neko');
	Debugger::dump($data2);	
		
	
出力
	array(
		'yagi' => 'ヤギ',
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		)
	)
	



検証2

	$data=array(
			'neko'=>'ネコ',
			'yagi'=>'ヤギ',
			'sakana'=>array('same'=>'サメ','medaka'=>'メダカ',),
			'sakana2'=>array('same'=>'サメ2','medaka'=>'メダカ2',),
	);
	
	$data2=Hash::remove($data, '{s}.medaka');
	Debugger::dump($data2);
		
	
出力
	array(
		'sakana' => array(
			'same' => 'サメ'
		),
		'sakana2' => array(
			'same' => 'サメ2'
		)
	)
	
※注意 兄弟要素neko,yagiまで削除される


検証3

	$data=array(
			'neko'=>'ネコ',
			'yagi'=>'ヤギ',
			'sakana'=>array('same'=>'サメ','medaka'=>'メダカ',),
			'sakana2'=>array('same'=>'サメ2','medaka'=>'メダカ2',),
	);
	
	$data2=Hash::remove($data, 'sakana.medaka');
	Debugger::dump($data2);
	
出力
	array(
		'neko' => 'ネコ',
		'yagi' => 'ヤギ',
		'sakana' => array(
			'same' => 'サメ'
		),
		'sakana2' => array(
			'same' => 'サメ2',
			'medaka' => 'メダカ2'
		)
	)
	



検証4

	$data=array(
			0=>array('id'=>1,'name'=>'アリ'),
			1=>array('id'=>2,'name'=>'ダニ'),
			2=>array('id'=>3,'name'=>'ノミ'),
			3=>array('id'=>4,'name'=>'シラミ'),
	);
	
	$data2=Hash::remove($data, '{n}.id');
	Debugger::dump($data2);
	
出力
	array(
		(int) 0 => array(
			'name' => 'アリ'
		),
		(int) 1 => array(
			'name' => 'ダニ'
		),
		(int) 2 => array(
			'name' => 'ノミ'
		),
		(int) 3 => array(
			'name' => 'シラミ'
		)
	)
	



参考

Hash::format | フォーマットされた文字を返す

$data2=Hash::format($data, array('{n}.id','{n}.name','{n}.val1'),'%2$s(%3$d) id=%1$d');
フォーマット文字は sprintf関数と同様の仕様のようである。

検証1

	$data=array(
			array('id'=>1,'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('id'=>3,'name'=>'カニ','val1'=>300),
			array('id'=>4,'name'=>'サメ','val1'=>400),
	);
	$data2=Hash::format($data, array('{n}.id','{n}.name','{n}.val1'),'%s-%s-%s');
	Debugger::dump($data2);
	
出力
	array(
		(int) 0 => '1 ネコ 100',
		(int) 1 => '2 ヤギ 200',
		(int) 2 => '3 カニ 300',
		(int) 3 => '4 サメ 400'
	)
	



検証2

	$data=array(
			array('id'=>1,'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('id'=>3,'name'=>'カニ','val1'=>300),
			array('id'=>4,'name'=>'サメ','val1'=>400),
	);
	$data2=Hash::format($data, array('{n}.name','{n}.id','{n}.val1'),'%s-%s-%s');
	Debugger::dump($data2);
	
出力
	array(
		(int) 0 => 'ネコ-1-100',
		(int) 1 => 'ヤギ-2-200',
		(int) 2 => 'カニ-3-300',
		(int) 3 => 'サメ-4-400'
	)
	



検証3

	$data=array(
			array('id'=>1,'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('id'=>3,'name'=>'カニ','val1'=>300),
			array('id'=>4,'name'=>'サメ','val1'=>400),
	);
	$data2=Hash::format($data, array('{n}.id','{n}.name','{n}.val1'),'%3$s-%2$s-%1$s');
	Debugger::dump($data2);
	
出力
	array(
		(int) 0 => '100-ネコ-1',
		(int) 1 => '200-ヤギ-2',
		(int) 2 => '300-カニ-3',
		(int) 3 => '400-サメ-4'
	)
	



検証4

	$data=array(
			array('id'=>1,'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('id'=>3,'name'=>'カニ','val1'=>300),
			array('id'=>4,'name'=>'サメ','val1'=>400),
	);
	$data2=Hash::format($data, array('{n}.id','{n}.name','{n}.val1'),'%2$s(%3$d) id=%1$d');
	Debugger::dump($data2);
	
出力
	array(
		(int) 0 => 'ネコ(100) id=1',
		(int) 1 => 'ヤギ(200) id=2',
		(int) 2 => 'カニ(300) id=3',
		(int) 3 => 'サメ(400) id=4'
	)
	



参考

Hash::flatten | 多次元配列を1次元配列化する

キーを連結して1つにまとめ、多次元配列を1次元配列化する。
1次元配列化し配列は「Hash::expand」で元の構造に戻すことができる。

検証1

	$data=array(
			'neko'=>'ネコ',
			'yagi'=>'ヤギ',
			'sakana'=>array('same'=>'サメ','medaka'=>'メダカ',),
	);
	$data2=Hash::flatten($data);
	Debugger::dump($data2);
	
出力
	array(
		'neko' => 'ネコ',
		'yagi' => 'ヤギ',
		'sakana.same' => 'サメ',
		'sakana.medaka' => 'メダカ'
	)
	



参考

Hash::expand | カンマ区切りのキーを分解して多次元配列化する

Hash::expand(array $data, string $separator = '.')

1次元配列のカンマ区切りキーを、カンマで分解して、多次元配列を作成する。
カンマ以外の区切り文字である場合、第2引数にてその区切り文字を指定する。

Hash::flattenとの連携

「Hash::flatten」では多次元配列を1次元配列に変換するが、 当関数で一次元化された配列を多次元に戻すことができる。

検証1

	$data=array(
		'neko' => 'ネコ',
		'yagi' => 'ヤギ',
		'sakana.same' => 'サメ',
		'sakana.medaka' => 'メダカ'
	);
	$data2=Hash::expand($data);
	Debugger::dump($data2);
	
出力
	array(
		'neko' => 'ネコ',
		'yagi' => 'ヤギ',
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		)
	)
	



検証2

	$data=array(
		'neko' => 'ネコ',
		'yagi' => 'ヤギ',
		'0:sakana:same' => 'サメ',
		'1:sakana:medaka' => 'メダカ'
	);
	$data2=Hash::expand($data,':');
	Debugger::dump($data2);
	
出力
	array(
		'neko' => 'ネコ',
		'yagi' => 'ヤギ',
		(int) 0 => array(
			'sakana' => array(
				'same' => 'サメ'
			)
		),
		(int) 1 => array(
			'sakana' => array(
				'medaka' => 'メダカ'
			)
		)
	)
	



参考

Hash::merge | 2つの配列をマージして1つにまとめる

検証1

	$data=	array(
		'neko' => 'ライオン',
		'yagi' => 'ヤギ',
		'sakana' => array(
			'same' => 'イルカ',
		)
	);
	$data2=	array(
		'neko' => 'ネコ',
		'kuma' => 'クマ',
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		)
	);
	$data3=Hash::merge($data,$data2);
	Debugger::dump($data3);
	
出力
	array(
		'neko' => 'ネコ',
		'yagi' => 'ヤギ',
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		),
		'kuma' => 'クマ'
	)
	



検証2

	$data=array(
			array('id'=>1,'name'=>'ヨコバイ','val1'=>999),
			array('id'=>2,'name'=>'センチュウ','val1'=>998),
			array('id'=>4,'name'=>'ゾウムシ','val1'=>997),
	);
	$data2=array(
			array('id'=>1,'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('id'=>3,'name'=>'カニ','val1'=>300),
			array('id'=>4,'name'=>'サメ','val1'=>400),
	);
	$data3=Hash::merge($data,$data2);
	Debugger::dump($data3);
	
出力
	array(
		(int) 0 => array(
			'id' => (int) 1,
			'name' => 'ネコ',
			'val1' => (int) 100
		),
		(int) 1 => array(
			'id' => (int) 2,
			'name' => 'ヤギ',
			'val1' => (int) 200
		),
		(int) 2 => array(
			'id' => (int) 3,
			'name' => 'カニ',
			'val1' => (int) 300
		),
		(int) 3 => array(
			'id' => (int) 4,
			'name' => 'サメ',
			'val1' => (int) 400
		)
	)
	



参考

Hash::dimensions | 先頭から次元数を取得する

static Hash::dimensions(array $data)
配列の深さを調べ、次元数として取得する。
配列の先頭値から深さを調べている。

検証1

	$data=array(
			array('a'=>array('b'=>array('c')),'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
	);
	$cnt=Hash::dimensions($data);
	Debugger::dump($cnt);
	
出力
	(int) 4
	



検証2

	$data=array(
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('a'=>array('b'=>array('c')),'name'=>'ネコ','val1'=>100),
	);
	$cnt=Hash::dimensions($data);
	Debugger::dump($cnt);
	
出力
	(int) 2
	



参考

Hash::maxDimensions | 最大の次元数を取得する

static Hash::maxDimensions(array $data)
配列から最も深い次元数を調べる。
「Hash::dimensions 」と同様な処理ではあるが、こちらの処理速度は遅いはずである。

検証1

	$data=array(
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('a'=>array('b'=>array('c')),'name'=>'ネコ','val1'=>100),
	);
	$cnt=Hash::maxDimensions($data);
	Debugger::dump($cnt);
	
出力
	(int) 4
	



参考

Hash::sort | パスで指定した値で並べ替える

static Hash::sort(array $data, $path, $dir, $type = 'regular')

検証1

	$data=array(
			array('id'=>1,'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('id'=>3,'name'=>'カニ','val1'=>300),
			array('id'=>4,'name'=>'サメ','val1'=>400),
	);
	$data2=Hash::sort($data,'{n}.name','asc');
	Debugger::dump($data2);
	
出力
	array(
		(int) 0 => array(
			'id' => (int) 3,
			'name' => 'カニ',
			'val1' => (int) 300
		),
		(int) 1 => array(
			'id' => (int) 4,
			'name' => 'サメ',
			'val1' => (int) 400
		),
		(int) 2 => array(
			'id' => (int) 1,
			'name' => 'ネコ',
			'val1' => (int) 100
		),
		(int) 3 => array(
			'id' => (int) 2,
			'name' => 'ヤギ',
			'val1' => (int) 200
		)
	)
	



検証2

	$data=array(
			array('id'=>1,'name'=>'ネコ','val1'=>100),
			array('id'=>2,'name'=>'ヤギ','val1'=>200),
			array('id'=>3,'name'=>'カニ','val1'=>300),
			array('id'=>4,'name'=>'サメ','val1'=>400),
	);
	$data2=Hash::sort($data,'{n}.val1','desc');
	Debugger::dump($data2);
	
出力
	array(
		(int) 0 => array(
			'id' => (int) 4,
			'name' => 'サメ',
			'val1' => (int) 400
		),
		(int) 1 => array(
			'id' => (int) 3,
			'name' => 'カニ',
			'val1' => (int) 300
		),
		(int) 2 => array(
			'id' => (int) 2,
			'name' => 'ヤギ',
			'val1' => (int) 200
		),
		(int) 3 => array(
			'id' => (int) 1,
			'name' => 'ネコ',
			'val1' => (int) 100
		)
	)
	



参考

Hash::normalize::diff | 2つの配列から差分を抽出

値が異なっているものや、キー有無の差分だけを抽出している。

1次元配列のみ有効である。
2次元目以降は配列単位で一致するかどうか見ており、配列中の値が1つでも異なれば、配列単位で不一致とみなされる。(検証2を参考)

検証1

	$data=	array(
		'neko' => 'ネコ',
		'kani' => 'カニ',
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		)
	);
	$data2=	array(
		'neko' => 'ネコ',
		'kani' => 'えび',
		'kuma' => 'クマ',
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		)
	);
	$data3=Hash::diff($data,$data2);
	Debugger::dump($data3);
	
出力
	array(
		'kani' => 'カニ',
		'kuma' => 'クマ'
	)
	



検証2

	$data=	array(
		'neko' => 'ネコ',
		'kani' => 'カニ',
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		)
	);
	$data2=	array(
		'neko' => 'ネコ',
		'kani' => 'カニ',
		'sakana' => array(
			'same' => 'イルカ',
			'medaka' => 'メダカ'
		)
	);
	$data3=Hash::diff($data,$data2);
	Debugger::dump($data3);
	$data3=Hash::mergeDiff($data,$data2);
	Debugger::dump($data3);
	
出力
	array(
		'sakana' => array(
			'same' => 'サメ',
			'medaka' => 'メダカ'
		)
	)
	



参考