Failed Conditions
Push — master ( 6673f1...4ab425 )
by Arnold
10:03
created

iterable_unwind()   C

Complexity

Conditions 16
Paths 45

Size

Total Lines 59
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 37
nc 45
nop 4
dl 0
loc 59
rs 5.5666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php /** @noinspection PhpVariableVariableInspection */
2
3
declare(strict_types=1);
4
5
namespace Improved;
6
7
/**
8
 * Deconstruct an iterable property/item for each element. The result is one element for each item in the iterable
9
 * property.
10
 *
11
 * @param iterable        $iterable      Iterable holding arrays or objects
12
 * @param int|string      $column
13
 * @param int|string|null $mapKey        The name of a new property to hold the array index of the element
14
 * @param bool            $preserveKeys  Preserve the keys of the iterable (will result in duplicate keys)
15
 * @return \Generator
16
 */
17
function iterable_unwind(iterable $iterable, $column, $mapKey = null, bool $preserveKeys = false): \Generator
18
{
19
    $counter = 0;
20
21
    $setArray = function ($element, $value, $key) use ($column, $mapKey) {
22
        return array_merge($element, [$column => $value], $mapKey === null ? [] : [$mapKey => $key]);
23
    };
24
25
    $setArrayAccess = function ($element, $value, $key) use ($column, $mapKey) {
26
        $copy = clone $element;
27
28
        $copy[$column] = $value;
29
        if ($mapKey !== null) {
30
            $copy[$mapKey] = $key;
31
        }
32
33
        return $copy;
34
    };
35
36
    $setObject = function ($element, $value, $key) use ($column, $mapKey) {
37
        $copy = clone $element;
38
39
        $copy->$column = $value;
0 ignored issues
show
introduced by
Variable property access on mixed.
Loading history...
40
        if ($mapKey !== null) {
41
            $copy->$mapKey = $key;
0 ignored issues
show
introduced by
Variable property access on mixed.
Loading history...
42
        }
43
44
        return $copy;
45
    };
46
47
    foreach ($iterable as $topKey => $element) {
48
        $set = null;
49
        $iterated = false;
50
51
        if (is_array($element)) {
52
            $value = $element[$column] ?? null;
53
            $set = $setArray;
54
        } elseif ($element instanceof \ArrayAccess) {
55
            $value = $element[$column] ?? null;
56
            $set = $setArrayAccess;
57
        } elseif (is_object($element) && !$element instanceof \DateTimeInterface) {
58
            $value = $element->$column ?? null;
0 ignored issues
show
introduced by
Variable property access on object.
Loading history...
59
            $set = $setObject;
60
        } else {
61
            $value = null;
62
        }
63
64
        if (!is_iterable($value) || $set === null) {
65
            yield ($preserveKeys ? $topKey : $counter++) => $element;
66
            continue;
67
        }
68
69
        foreach ($value as $key => $item) {
70
            $iterated = true;
71
            yield ($preserveKeys ? $topKey : $counter++) => $set($element, $item, $key);
72
        }
73
74
        if (!$iterated) {
75
            yield ($preserveKeys ? $topKey : $counter++) => $set($element, null, null);
76
        }
77
    }
78
}
79