Completed
Pull Request — master (#128)
by Christoffer
02:13
created

keyValMap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Util;
4
5
use Digia\GraphQL\Error\InvariantException;
6
7
/**
8
 * @param bool   $condition
9
 * @param string $message
10
 * @throws InvariantException
11
 */
12
function invariant(bool $condition, string $message)
13
{
14
    if (!$condition) {
15
        throw new InvariantException($message);
16
    }
17
}
18
19
/**
20
 * Given `[A, B, C]` returns `'A, B or C'`.
21
 *
22
 * @param array $items
23
 * @return string
24
 */
25
function orList(array $items): string
26
{
27
    static $MAX_LENGTH = 5;
28
29
    $selected = \array_slice($items, 0, $MAX_LENGTH);
30
    $count    = \count($selected);
31
    $index    = 0;
32
33
    return $count === 1
34
        ? $selected[0]
35
        : \array_reduce($selected, function ($list, $item) use ($count, &$index) {
36
            $list .= ($index > 0 && $index < ($count - 1) ? ', ' : '') . ($index === ($count - 1) ? ' or ' : '') .
37
                $item;
38
            $index++;
39
            return $list;
40
        }, '');
41
}
42
43
/**
44
 * Given an invalid input string and a list of valid options, returns a filtered
45
 * list of valid options sorted based on their similarity with the input.
46
 *
47
 * @param string $input
48
 * @param array  $options
49
 * @return array
50
 */
51
function suggestionList(string $input, array $options): array
52
{
53
    $optionsByDistance = [];
54
    $oLength = \count($options);
55
    $inputThreshold = \strlen($input) / 2;
56
57
    /** @noinspection ForeachInvariantsInspection */
58
    for ($i = 0; $i < $oLength; $i++) {
59
        // Comparison must be case-insenstive.
60
        $distance = \levenshtein(\strtolower($input), \strtolower($options[$i]));
61
        $threshold = \max($inputThreshold, \strlen($options[$i]) / 2, 1);
62
        if ($distance <= $threshold) {
63
            $optionsByDistance[$options[$i]] = $distance;
64
        }
65
    }
66
67
    $result = \array_keys($optionsByDistance);
68
69
    \usort($result, function ($a, $b) use ($optionsByDistance) {
70
        return $optionsByDistance[$a] - $optionsByDistance[$b];
71
    });
72
73
    return $result;
74
}
75
76
/**
77
 * Given `[A, B, C]` returns `'"A", "B" or "C"'`.
78
 *
79
 * @param array $items
80
 * @return string
81
 */
82
function quotedOrList(array $items): string
83
{
84
    return orList(array_map(function ($item) {
85
        return '"' . $item . '"';
86
    }, $items));
87
}
88
89
90
91
/**
92
 * @param array    $array
93
 * @param callable $fn
94
 * @return bool
95
 */
96
function arrayEvery(array $array, callable $fn): bool
97
{
98
    return array_reduce($array, function ($result, $value) use ($fn) {
99
        return $result && $fn($value);
100
    }, true);
101
}
102
103
/**
104
 * @param array    $array
105
 * @param callable $fn
106
 * @return mixed
107
 */
108
function arraySome(array $array, callable $fn)
109
{
110
    return array_reduce($array, function ($result, $value) use ($fn) {
111
        return $result || $fn($value);
112
    });
113
}
114
115
/**
116
 * @param array    $array
117
 * @param callable $predicate
118
 * @return mixed|null
119
 */
120
function find(array $array, callable $predicate)
121
{
122
    foreach ($array as $value) {
123
        if ($predicate($value)) {
124
            return $value;
125
        }
126
    }
127
128
    return null;
129
}
130
131
/**
132
 * @param array    $array
133
 * @param callable $keyFn
134
 * @return array
135
 */
136
function keyMap(array $array, callable $keyFn): array
137
{
138
    return array_reduce($array, function ($map, $item) use ($keyFn) {
139
        $map[$keyFn($item)] = $item;
140
        return $map;
141
    }, []);
142
}
143
144
/**
145
 * @param array    $array
146
 * @param callable $keyFn
147
 * @param callable $valFn
148
 * @return array
149
 */
150
function keyValueMap(array $array, callable $keyFn, callable $valFn): array
151
{
152
    return array_reduce($array, function ($map, $item) use ($keyFn, $valFn) {
153
        $map[$keyFn($item)] = $valFn($item);
154
        return $map;
155
    }, []);
156
}
157
158
/**
159
 * @param $value
160
 * @return string
161
 */
162
function toString($value): string
163
{
164
    if (\is_object($value) && method_exists($value, '__toString')) {
165
        return $value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value returns the type object which is incompatible with the type-hinted return string.
Loading history...
166
    }
167
    if (\is_object($value)) {
168
        return 'Object';
169
    }
170
    if (\is_array($value)) {
171
        return 'Array';
172
    }
173
    if (\is_callable($value)) {
174
        return 'Function';
175
    }
176
    if ($value === '') {
177
        return '(empty string)';
178
    }
179
    if ($value === null) {
180
        return 'null';
181
    }
182
    if ($value === true) {
183
        return 'true';
184
    }
185
    if ($value === false) {
186
        return 'false';
187
    }
188
    if (\is_string($value)) {
189
        return "\"{$value}\"";
190
    }
191
    if (is_scalar($value)) {
192
        return (string)$value;
193
    }
194
    return \gettype($value);
195
}
196