PackedItemList   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 73
ccs 17
cts 17
cp 1
rs 10
c 0
b 0
f 0
wmc 7

5 Methods

Rating   Name   Duplication   Size   Complexity  
A count() 0 3 1
A insert() 0 3 1
A compare() 0 6 2
A asItemArray() 0 5 1
A getIterator() 0 8 2
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 ArrayIterator;
12
use Countable;
13
use IteratorAggregate;
14
use Traversable;
15
use function array_map;
16
use function count;
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
    /**
34
     * Has this list already been sorted?
35
     *
36
     * @var bool
37
     */
38
    private $isSorted = false;
39
40
    /**
41
     * @param PackedItem $item
42
     */
43 21
    public function insert(PackedItem $item): void
44
    {
45 21
        $this->list[] = $item;
46 21
    }
47
48
    /**
49
     * @return Traversable
50
     */
51 21
    public function getIterator(): Traversable
52
    {
53 21
        if (!$this->isSorted) {
54 21
            usort($this->list, [$this, 'compare']);
55 21
            $this->isSorted = true;
56
        }
57
58 21
        return new ArrayIterator($this->list);
59
    }
60
61
    /**
62
     * Number of items in list.
63
     *
64
     * @return int
65
     */
66 7
    public function count(): int
67
    {
68 7
        return count($this->list);
69
    }
70
71
    /**
72
     * Get copy of this list as a standard PHP array.
73
     *
74
     * @internal
75
     *
76
     * @return Item[]
77
     */
78 1
    public function asItemArray(): array
79
    {
80
        return array_map(function (PackedItem $packedItem) {
81 1
            return $packedItem->getItem();
82 1
        }, $this->list);
83
    }
84
85
    /**
86
     * @param PackedItem $itemA
87
     * @param PackedItem $itemB
88
     *
89
     * @return int
90
     */
91 19
    private function compare(PackedItem $itemA, PackedItem $itemB): int
92
    {
93 19
        $itemAVolume = $itemA->getItem()->getWidth() * $itemA->getItem()->getLength() * $itemA->getItem()->getDepth();
94 19
        $itemBVolume = $itemB->getItem()->getWidth() * $itemB->getItem()->getLength() * $itemB->getItem()->getDepth();
95
96 19
        return ($itemBVolume <=> $itemAVolume) ?: ($itemB->getItem()->getWeight() <=> $itemA->getItem()->getWeight());
97
    }
98
}
99