PackedItemList::compare()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 1
nop 2
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
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