四重奏/海顿

此包已被废弃且不再维护。未建议替代包。

集合操作库

v1.3.1 2015-10-21 09:16 UTC

README

Build Status Scrutinizer Code Quality Code Coverage Total Downloads Latest Stable Version Latest Unstable Version

4a65559a-03f3-11e5-8087-4cd0d7e114d2.jpg

这是一个可声明性地对数组进行乘法或列运算的库。其实施特点在于,对集合的各种运算仅通过声明性执行,除非使用foreach等迭代Set对象,否则不会进行内容扫描。

$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();

安装

composer require quartet/haydn

用法

集合声明(使用源对象)

$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;
}

特定集合

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

集合操作

ProductSet

Set#product(Set $target)

创建两个集合相乘的集合。(笛卡尔积)

$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)

对集合的每个元素进行某种加工后的结果集合。

  • 列选择
  • 列值的运算 - 分割成多行
$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)

从集合的元素中提取匹配项的集合。

$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来动态评估,而不是指定完全匹配的值。

new Matcher(['type' => function($value) {
    return strpos($value, ':') !== false;
}])

Devide

Set#devide(array $matchers)

通过指定多个Matcher,将每个Matcher对应到相应的集合。

$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)

将多个集合合并,返回连接后的集合。

$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

返回经过分组运算的集合。这里的分组运算是指,创建一个具有“键的数目”个组的集合,其中每个键的元素各自具有详细的集合。具体来说如下。

  • 存在键集合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

集合的数据供应源(数据源)。

  • ArraySource
  • SingleColumnArraySource
  • SingleRowSource

ArraySource

使用PHP数组(二维)作为数据源。

$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

使用只含有一列的PHP数组(一维)作为数据源。

$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

使用只含有一行的PHP数组(一维)作为数据源。

$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

源的列名映射

  • HashKeyColumnMapper
  • SimpleArrayColumnMapper
  • NullColumnMapper
  • ChainMapper

HashKeyColumnMapper

各行都是关联数组的数据源,使用关联数组的键名直接作为列名。

$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

为没有键的数组数据源提供列名。

$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

不使用列名映射。

$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

链式调用列名映射器。

支持

如果您发现错误或有疑问,或者想要请求功能,请在问题页面上创建一个issue或pull request。

版权

版权所有 (c) 2015 GOTO Hidenori,保留所有权利。

许可

BSD 2条款许可