Haydn
, (*1)
配列に対してかけ算や列演算を宣言的に指定できるライブラリ。
実装の特徴として、Setに対する各種演算は単に宣言的に行われるのみで、Setオブジェクトをforeach
等でイテレーションしないかぎり、中身の走査は行われない点。, (*2)
$fruits = [
['name' => 'Apple', 'price' => 100],
['name' => 'Banana', 'price' => 80],
];
$drinks = [
['name' => 'Yoghurt', 'price' => 200],
['name' => 'Soda', 'price' => 120],
['name' => 'Spirit', 'price' => 160],
];
$fruitSet = new Set(new ArraySource('fruit', $fruits, new HashKeyColumnMapper()));
$drinkSet = new Set(new ArraySource('drink', $drinks, new HashKeyColumnMapper()));
$fruitDrinkSet = $fruitSet->product($drinkSet);
$result = $fruitDrinkSet->toArray();
Install
composer require quartet/haydn
Usage
Set declaration (using source object)
$fruitsAssoc = [
['name' => 'Apple', 'price' => 100],
['name' => 'Banana', 'price' => 80],
];
$fruitsSet = new Set(new ArraySource('fruit', $fruitsAssoc, new HashKeyColumnMapper());
foreach ($fruitSet as $fruit) {
echo 'name:' . $fruit['name'] . ' price:' . $fruit['price'] . PHP_EOL;
}
Specific Sets
IdenticalSet
$fruitsAssoc = [
['name' => 'Apple', 'price' => 100],
['name' => 'Banana', 'price' => 80],
];
$fruitsSet = new Set(new ArraySource('fruit', $fruitsAssoc, new HashKeyColumnMapper());
$identicalSet = new IdenticalSet();
$all = $fruitSet->product($identicalSet);
// same as $fruitSet
$all = $identicalSet->product($fruitSet);
// same as $fruitSet
$all = $fruitSet->union($identicalSet);
// same as $fruitSet
$all = $identicalSet->union($fruitSet);
// same as $fruitSet
EmptySet
$fruitsAssoc = [
['name' => 'Apple', 'price' => 100],
['name' => 'Banana', 'price' => 80],
];
$fruitsSet = new Set(new ArraySource('fruit', $fruitsAssoc, new HashKeyColumnMapper());
$emptySet = new EmptySet();
$all = $fruitSet->product($emptySet);
// empty
$all = $emptySet->product($fruitSet);
// empty
$all = $fruitSet->union($emptySet);
// same as $fruitSet
$all = $emptySet->union($fruitSet);
// same as $fruitSet
Set operations
ProductSet
Set#product(Set $target)
, (*3)
2つのSetをかけたSetを作る。(デカルト積), (*4)
$fruits = [
['name' => 'Apple', 'price' => 100],
['name' => 'Banana', 'price' => 80],
];
$drinks = [
['name' => 'Yoghurt', 'price' => 200],
['name' => 'Soda', 'price' => 120],
['name' => 'Spirit', 'price' => 160],
];
$fruitSet = new Set(new ArraySource('fruit', $fruits, new HashKeyColumnMapper()));
$drinkSet = new Set(new ArraySource('drink', $drinks, new HashKeyColumnMapper()));
$fruitDrinkSet = $fruitSet->product($drinkSet);
SelectSet
Set#select(array $selectors)
, (*5)
Setの各要素に対して、何らかの加工を加えた結果のSet。, (*6)
$fruits = [
['name' => 'Apple', 'price' => 100],
['name' => 'Banana', 'price' => 80],
];
$fruitMenuSet = new Set(new ArraySource('fruit', $fruits, new HashKeyColumnMapper()))
->select([function($row) {
return [
'menu item name' => $row['name']
];
}]);
;
FilterSet
Set#filter(MatcherInterface $matcher)
, (*7)
Setの要素に対して、マッチしたものだけを取り出したSet。, (*8)
$products = [
['name' => 'Apple', 'price' => 100, 'type' => 'fruit'],
['name' => 'Yoghurt', 'price' => 200, 'type' => 'drink'],
['name' => 'Soda', 'price' => 120, 'type' => 'drink'],
['name' => 'Banana', 'price' => 80, 'type' => 'fruit'],
['name' => 'Spirit', 'price' => 160, 'type' => 'drink'],
];
$fruitSet = new Set(new ArraySource('product', $products, new HashKeyColumnMapper()))
->filter(new Matcher(['type' => 'fruit']));
;
Matcherは、対象列の名前をキーとして、完全一致する文字列を指定する。
また、完全一致の値ではなく、Closureを渡して動的に評価させることも可能。, (*9)
new Matcher(['type' => function($value) {
return strpos($value, ':') !== false;
}])
Devide
Set#devide(array $matchers)
, (*10)
Matcherを複数指定して、それぞれのMatcherに対応するSetへ分割する。, (*11)
$products = [
['name' => 'Apple', 'price' => 100, 'type' => 'fruit'],
['name' => 'Yoghurt', 'price' => 200, 'type' => 'drink'],
['name' => 'Soda', 'price' => 120, 'type' => 'drink'],
['name' => 'Banana', 'price' => 80, 'type' => 'fruit'],
['name' => 'Spirit', 'price' => 160, 'type' => 'drink'],
];
$productSet = new Set(new ArraySource('product', $products, new HashKeyColumnMapper()));
list($fruitSet, $drinkSet) = $productSet->devide([
'fruit' => new Matcher(['type' => 'fruit']),
'drink' => new Matcher(['type' => 'drink']),
]);
Union
Set#union(Set $target)
, (*12)
複数のSetを結合して、つながったSetを返す。, (*13)
$fruits = [
['name' => 'Apple', 'price' => 100],
['name' => 'Banana', 'price' => 80],
];
$drinks = [
['name' => 'Yoghurt', 'price' => 200],
['name' => 'Soda', 'price' => 120],
['name' => 'Spirit', 'price' => 160],
];
$fruitSet = new Set(new ArraySource('fruit', $fruits, new HashKeyColumnMapper()));
$drinkSet = new Set(new ArraySource('drink', $drinks, new HashKeyColumnMapper()));
$allSet = $fruitSet->union($drinkSet);
Grouping
グルーピング演算したSetを返す。ここでグルーピング演算とは、キーとなる集合の各要素それぞれがさらに明細の集合を有するような、「キーの数だけグループを持つ集合」を作成することを指す。
具体的には以下のとおり。, (*14)
- キー集合Aがあり、
- Aの各要素a1,a2,a3,...ぞれに対して明細集合B1,B2,B3,...を作成したい場合に、
- Aのある要素anを以下のような行に展開し、それをa1,a2,a3,...すべてに適用する
- ヘッダー行(anグループの先頭を宣言する行)
- 明細集合Bnの各行
- フッター行(anグループの末尾を宣言する行)
$k1 = new Set(new SingleColumnArraySource('k1', ['あいう', 'かきく']));
$k2 = new Set(new SingleColumnArraySource('k2', ['abc', 'def']));
$k3 = new Set(new SingleColumnArraySource('k3', ['123', '456']));
$g1 = new Set\GroupingSet(
// Key Set
$k1->product($k2),
// Header Generator
function ($r) { return ['type' => 'header', 'name' => $r['k1'] . '-' . $r['k2']]; },
// Detail Set Generator
function ($r) use ($k3) {
$set = new Set(new SingleRowSource('k1k2', $r));
$resultSet = $set->product($k3)->select([function ($r) {
return [
'type' => 'detail',
'content' => $r['k1'] . ' ' . $r['k2'] . ' ' . $r['k3'],
];
}]);
return $resultSet;
},
// Footer Generator
null
);
$all = $g1->toArray();
var_dump($all);
// [
// 'type' => 'header',
// 'name' => 'あいう-abc',
// ], [
// 'type' => 'detail',
// 'content' => 'あいう abc 123',
// ], [
// 'type' => 'detail',
// 'content' => 'あいう abc 456',
// ], [
// 'type' => 'header',
// 'name' => 'あいう-def',
// ], [
// 'type' => 'detail',
// 'content' => 'あいう def 123',
// ], [
// 'type' => 'detail',
// 'content' => 'あいう def 456',
// ], [
// 'type' => 'header',
// 'name' => 'かきく-abc',
// ], [
// 'type' => 'detail',
// 'content' => 'かきく abc 123',
// ], [
// 'type' => 'detail',
// 'content' => 'かきく abc 456',
// ], [
// 'type' => 'header',
// 'name' => 'かきく-def',
// ], [
// 'type' => 'detail',
// 'content' => 'かきく def 123',
// ], [
// 'type' => 'detail',
// 'content' => 'かきく def 456',
// ],
Source
Setのデータ供給源(データソース)。, (*15)
- ArraySource
- SingleColumnArraySource
- SingleRowSource
ArraySource
PHPの配列(2次元)をデータソースとして利用する。, (*16)
$fruitArray = [
['id' => 1, 'name' => 'Apple'],
['id' => 2, 'name' => 'Banana'],
['id' => 3, 'name' => 'Lemon'],
];
$fruitSet = new Set(new ArraySource('fruit', $fruitArray, new HashKeyColumnMapper()));
$output = $fruitSet->toArray();
var_dump($output);
// ['id' => 1, 'name' => 'Apple'],
// ['id' => 2, 'name' => 'Banana'],
// ['id' => 3, 'name' => 'Lemon']
SingleColumnArraySource
1列のみのPHP配列(1次元)をデータソースとして利用する。, (*17)
$fruitArray = [
'Apple',
'Banana',
'Lemon'];
$fruitSet = new Set(new SingleColumnArraySource('fruit', $fruitArray, new NullColumnMapper()));
$output = $fruitSet->toArray();
var_dump($output);
// ['fruit' => 'Apple'],
// ['fruit' => 'Banana'],
// ['fruit' => 'Lemon'],
SingleRowSource
1行のみのPHP配列(1次元)をデータソースとして利用する。, (*18)
$fruitArray = ['1','Apple','140'];
$fruitSet = new Set(new SingleRowSource('fruit', $fruitArray, new SimpleArrayColumnMapper([
'id', 'name', 'price'
])));
$output = $fruitSet->toArray();
var_dump($output);
// ['id'=>1, 'name' => 'Apple', 'price'=>140],
ColumnMapper
Sourceの列名マッピング, (*19)
- HashKeyColumnMapper
- SimpleArrayColumnMapper
- NullColumnMapper
- ChainMapper
HashKeyColumnMapper
各行が連想配列になっているデータソースで、連想配列のキー名をそのまま列名として使う。, (*20)
$fruitArray = [
['id' => 1, 'name' => 'Apple'],
['id' => 2, 'name' => 'Banana'],
['id' => 3, 'name' => 'Lemon'],
];
$fruitSet = new Set(new ArraySource('fruit', $fruitArray, new HashKeyColumnMapper()));
$output = $fruitSet->toArray();
var_dump($output);
// ['id' => 1, 'name' => 'Apple'],
// ['id' => 2, 'name' => 'Banana'],
// ['id' => 3, 'name' => 'Lemon']
SimpleArrayColumnMapper
キーの無い配列データソースに、列名を配列で与える。, (*21)
$fruitColumn = ['id', 'name'];
$fruitArray = [
[1, 'Apple'],
[2, 'Banana'],
[3, 'Lemon'],
];
$fruitSet = new Set(new ArraySource('fruit', $fruitArray, new SimpleArrayColumnMapper($fruitColumn)));
$output = $fruitSet->toArray();
var_dump($output);
// ['id' => 1, 'name' => 'Apple'],
// ['id' => 2, 'name' => 'Banana'],
// ['id' => 3, 'name' => 'Lemon']
NullColumnMapper
列名マップを使わない。, (*22)
$fruitArray = [
[1, 'Apple'],
[2, 'Banana'],
[3, 'Lemon'],
];
$fruitSet = new Set(new ArraySource('fruit', $fruitArray, new NullColumnMapper()));
$output = $fruitSet->toArray();
var_dump($output);
// [0 => 1, 1 => 'Apple'],
// [0 => 2, 1 => 'Banana'],
// [0 => 3, 1 => 'Lemon']
ChainMapper
列名マッパーを複数チェインさせる。, (*23)
Support
If you find a bug or have a question, or want to request a feature, create an issue or pull request for it on Issues., (*24)
Copyright
Copyright (c) 2015 GOTO Hidenori, All rights reserved., (*25)
License
The BSD 2-Clause License, (*26)