LoginSignup
2
2

More than 5 years have passed since last update.

ある数値をある数値で分割して配列で得る

Last updated at Posted at 2016-04-10

たとえば、「Aという商品を1,000点入荷する」という処理を行うとき、メモリなどの関係で一気にレコードを処理することができないので、100点ずつに分割して処理したいとします。

そのため、1,000という数値を100が10個含まれた配列に変換したかったのですが、意外とそういうニーズってないのか、ベストプラクティスを見つけられませんでした。。。これよりいい方法があればぜひ教えてほしいです。。。

分割処理

ProcedureUtil.php
class ProcedureUtil
{
    /**
     * @param int $quantity 分割したい数値
     * @param int $divisor 除数
     *
     * @return array 分割された配列
     */
    public static function divideQuantity($quantity, $divisor)
    {
        $quantity = (int)$quantity;
        $divisor = (int)$divisor;

        if ($quantity < 0) {
            // 0未満の数値は扱わない
            throw new \InvalidArgumentException(
                sprintf(
                    'Argument 1 passed to divideQuantity() must be number and greater than 0, %s is given',
                    $divisor
                )
            );

        } elseif (0 === $quantity) {
            // 0の場合は、そのまま配列に格納して返却
            return array(0);
        }

        if ($divisor <= 0) {
            // 除数に0以下の数値は扱わない
            throw new \InvalidArgumentException(
                sprintf(
                    'Argument 2 passed to divideQuantity() must be number and greater than 1, %s is given',
                    $divisor
                )
            );
        }

        $quotient = ceil($quantity / $divisor);

        $ret = array();

        for ($index = 1; $index <= $quotient; $index++) {
            if ($quantity - $divisor > 0) {
                $ret[] = $divisor;
                $quantity -= $divisor;

            } else {
                $ret[] = $quantity;
            }
        }

        return $ret;
    }

単体テスト

ProcedureUtilTest.php
class ProcedureUtilTest extends \PHPUnit_Framework_TestCase
{
    public function testDivideQuantity()
    {
        $result = ProcedureUtil::divideQuantity(1, 1);
        $expected = array(1);
        $this->assertEquals($expected, $result);

        $result = ProcedureUtil::divideQuantity(0, 1);
        $expected = array(0);
        $this->assertEquals($expected, $result);

        $result = ProcedureUtil::divideQuantity(1, 10);
        $expected = array(1);
        $this->assertEquals($expected, $result);

        $result = ProcedureUtil::divideQuantity(0, 10);
        $expected = array(0);
        $this->assertEquals($expected, $result);

        $result = ProcedureUtil::divideQuantity(10, 10);
        $expected = array(10);
        $this->assertEquals($expected, $result);

        $result = ProcedureUtil::divideQuantity(11, 10);
        $expected = array(10, 1);
        $this->assertEquals($expected, $result);

        $result = ProcedureUtil::divideQuantity(20, 10);
        $expected = array(10, 10);
        $this->assertEquals($expected, $result);

        $result = ProcedureUtil::divideQuantity(21, 10);
        $expected = array(10, 10, 1);
        $this->assertEquals($expected, $result);
    }

    /**
     * @expectedException \InvalidArgumentException
     */
    public function testDivideQuantityWithException()
    {
        ProcedureUtil::divideQuantity(1, 0);
        ProcedureUtil::divideQuantity(1, -1);
    }

使用例

HogeLogic.php
class HogeLogic
{
    public function process()
    {
        foreach (ProcedureUtil::divideQuantity(1000, 100) as $divided) {
            $this->doSomething(divided);
        }
    }
2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2