Passed
Push — master ( 0bad10...5719ef )
by Doug
02:22 queued 10s
created

PackedItemList::getWeight()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace DVDoug\BoxPacker;
10
11
use function array_map;
12
use ArrayIterator;
13
use function count;
14
use Countable;
15
use IteratorAggregate;
16
use Traversable;
17
use function usort;
18
19
/**
20
 * List of packed items, ordered by volume.
21
 *
22
 * @author Doug Wright
23
 */
24
class PackedItemList implements Countable, IteratorAggregate
25
{
26
    /**
27
     * List containing items.
28
     *
29
     * @var PackedItem[]
30
     */
31
    private $list = [];
32
33
    private $weight = 0;
34
35
    /**
36
     * Has this list already been sorted?
37
     *
38
     * @var bool
39
     */
40
    private $isSorted = false;
41
42 68
    public function insert(PackedItem $item): void
43
    {
44 68
        $this->list[] = $item;
45 68
        $this->weight += $item->getItem()->getWeight();
46 68
    }
47
48
    /**
49
     * @return Traversable<PackedItem>
50
     */
51 68
    public function getIterator(): Traversable
52
    {
53 68
        if (!$this->isSorted) {
54 68
            usort($this->list, [$this, 'compare']);
55 68
            $this->isSorted = true;
56
        }
57
58 68
        return new ArrayIterator($this->list);
59
    }
60
61
    /**
62
     * Number of items in list.
63
     */
64 68
    public function count(): int
65
    {
66 68
        return count($this->list);
67
    }
68
69
    /**
70
     * Get copy of this list as a standard PHP array.
71
     *
72
     * @internal
73
     *
74
     * @return Item[]
75
     */
76 8
    public function asItemArray(): array
77
    {
78 8
        return array_map(function (PackedItem $packedItem) {
79 8
            return $packedItem->getItem();
80 8
        }, $this->list);
81
    }
82
83
    /**
84
     * Get total volume of these items.
85
     */
86 68
    public function getVolume(): int
87
    {
88 68
        $volume = 0;
89
90 68
        foreach ($this->list as $item) {
91 68
            $volume += $item->getVolume();
92
        }
93
94 68
        return $volume;
95
    }
96
97
    /**
98
     * Get total weight of these items.
99
     */
100 68
    public function getWeight(): int
101
    {
102 68
        return $this->weight;
103
    }
104
105 60
    private function compare(PackedItem $itemA, PackedItem $itemB): int
106
    {
107 60
        $itemAVolume = $itemA->getItem()->getWidth() * $itemA->getItem()->getLength() * $itemA->getItem()->getDepth();
108 60
        $itemBVolume = $itemB->getItem()->getWidth() * $itemB->getItem()->getLength() * $itemB->getItem()->getDepth();
109
110 60
        return ($itemBVolume <=> $itemAVolume) ?: ($itemB->getItem()->getWeight() <=> $itemA->getItem()->getWeight());
111
    }
112
}
113