Passed
Push — 1.x ( 0e8de8...457fa0 )
by Doug
30:53
created

ItemList::fromArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
8
namespace DVDoug\BoxPacker;
9
10
/**
11
 * List of items to be packed, ordered by volume.
12
 *
13
 * @author Doug Wright
14
 */
15
class ItemList extends \SplMaxHeap
16
{
17
    /**
18
     * Compare elements in order to place them correctly in the heap while sifting up.
19
     *
20
     * @see \SplMaxHeap::compare()
21
     *
22
     * @param mixed $itemA
23
     * @param mixed $itemB
24
     *
25
     * @return int
26
     */
27
    public function compare($itemA, $itemB)
28
    {
29
        if ($itemA->getVolume() > $itemB->getVolume()) {
30
            return 1;
31
        } elseif ($itemA->getVolume() < $itemB->getVolume()) {
32
            return -1;
33
        } elseif ($itemA->getWeight() !== $itemB->getWeight()) {
34
            return $itemA->getWeight() - $itemB->getWeight();
35
        } elseif ($itemA->getDescription() < $itemB->getDescription()) {
36
            return 1;
37
        } else {
38
            return -1;
39
        }
40
    }
41
42
    /**
43
     * Do a bulk create.
44
     *
45
     * @param  Item[]   $items
46
     * @return ItemList
47
     */
48
    public static function fromArray(array $items)
49
    {
50
        $list = new static();
51
        foreach ($items as $item) {
52
            $list->insert($item);
53
        }
54
        return $list;
55
    }
56
57
    /**
58
     * Get copy of this list as a standard PHP array.
59
     *
60
     * @return Item[]
61
     */
62
    public function asArray()
63
    {
64
        $return = [];
65
        foreach (clone $this as $item) {
66
            $return[] = $item;
67
        }
68
69
        return $return;
70
    }
71
72
    /**
73
     * @internal
74
     *
75
     * @param  int      $n
76
     * @return ItemList
77
     */
78
    public function topN($n)
79
    {
80
        $workingList = clone $this;
81
        $topNList = new self();
82
        $i = 0;
83
        while(!$workingList->isEmpty() && $i < $n) {
84
            $topNList->insert($workingList->extract());
85
            $i++;
86
        }
87
88
        return $topNList;
89
    }
90
91
    /**
92
     * Remove item from list.
93
     *
94
     * @param Item $item
95
     */
96
    public function remove(Item $item)
97
    {
98
        $workingSet = [];
99
        while (!$this->isEmpty()) {
100
            $workingSet[] = $this->extract();
101
        }
102
103
        $removed = false; // there can be multiple identical items, ensure that only 1 is removed
104
        foreach ($workingSet as $workingSetItem) {
105
            if (!$removed && $workingSetItem === $item) {
106
                $removed = true;
107
            } else {
108
                $this->insert($workingSetItem);
109
            }
110
        }
111
112
    }
113
}
114