speelpenning / binary-search-collection
为 Laravel 的集合扩展了二分搜索支持。
v1.0
2016-04-15 15:04 UTC
Requires
- illuminate/support: >=5.0
Requires (Dev)
- fzaninotto/faker: ^1.5
- phpunit/phpunit: ~4.8
- symfony/stopwatch: ^2.8
This package is auto-updated.
Last update: 2024-09-08 17:31:15 UTC
README
当处理包含具有唯一标识符的对象的大型数据集时,此软件包非常有用。
入门
要求
- illuminate/support: >= 5.0
安装
使用 Composer 引入软件包
composer require speelpenning/binary-search-collection
使用方法
如果您有以不同格式(如 csv 和 XML)存储的结构化数据,并且需要合并数据以生成报告,您只需定义一些模型并创建一个返回包含模型的集合的读取器。
示例用例
假设我们有以下文件
- 一个包含 200,000 个产品的 XML 文件(产品编号、描述等)
- 一个包含 70,000 个价格(产品编号、含税价格、净价、列表价格)的 csv 价格表
为了向“我们的客户”发送价格表,我们需要创建一个包含产品编号、描述、列表价格和含税价格的 csv 文件。
首先,我们需要两个模型,比如 Product 和 Price,它们包含文件中定义的属性。然后,我们为 XML 文件(即 ProductsReader)和 csv 文件(即 PriceReader)创建读取器。读取器在构造函数中接受二分排序集合,并用文件中的模型填充集合。读取器返回集合。
现在我们接近目标:为我们的客户生成 csv 价格表。为此,我们创建了一个写入器(例如 CustomerPriceListWriter),它在构造函数中接受两个读取器。写入器遍历包含 Price 模型的集合,同时使用二分搜索在另一个集合中查找 Product 记录。然后将两个模型的数据合并,并将带有客户价格的数据写入 csv 文件。
<?php class CustomerPriceListWriter { /** * @var ProductReader */ protected $productReader; /** * @var PriceReader */ protected $priceReader; /** * Create a new customer price list writer instance. * * @param ProductReader $productReader * @param PriceReader $priceReader */ public function __construct(ProductReader $productReader, PriceReader $priceReader) { $this->productReader = $productReader; $this->priceReader = $priceReader; } protected function write($productsFilename, $pricesFilename, $targetFilename = null) { // First we read the products and prices file, which both // return a collection that supports binary search. $products = $this->productReader->read($productsFilename); $prices = $this->priceReader->read($pricesFilename); // Prepare the array with CSV lines. $csv = [$this->toCsv([ 'Product Number', 'Description', 'List price', 'Your price' ])]; foreach ($prices as $price) { $product = $products->find($price->product_number); $csv[] = $this->toCsv([ $product->product_number, $product->description, $price->list_price, $price->gross_price ]); } $targetFilename = is_null($targetFilename) ? 'customer-prices-'.date('YmdHis').'.csv' : $targetFilename; file_put_contents($targetFilename, implode("\n", $csv)); } protected function toCsv(array $values) { foreach ($values as $key => $value) { $value[$key] = is_numeric($value) ? $value : "\"{$value}\""; } return implode(',', $values); } }